@posiwise/resource-module 0.0.149 → 0.0.151

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 (108) hide show
  1. package/esm2022/index.mjs +22 -3
  2. package/esm2022/lib/public/components/reslease-note-card/release-note-card.component.mjs +13 -9
  3. package/esm2022/lib/public/components/resource-blogs/resource-blog-top-banner/resource-blog-top-banner.component.mjs +6 -6
  4. package/esm2022/lib/public/components/resource-blogs/resource-blog.component.mjs +6 -6
  5. package/esm2022/lib/public/components/resource-case-studies/case-studies-cards/case-studies-cards.component.mjs +18 -12
  6. package/esm2022/lib/public/components/resource-case-studies/resource-case-studies.component.mjs +10 -10
  7. package/esm2022/lib/public/components/resource-company-card/resource-company-card.component.mjs +7 -8
  8. package/esm2022/lib/public/components/resource-contact-us/resource-contact-us.component.mjs +510 -0
  9. package/esm2022/lib/public/components/resource-contact-us/resource-contact-us.module.mjs +77 -0
  10. package/esm2022/lib/public/components/resource-edit-card/resource-edit-card.component.mjs +5 -5
  11. package/esm2022/lib/public/components/resource-edit-card-lazy/resource-edit-card-lazy.component.mjs +75 -0
  12. package/esm2022/lib/public/components/resource-integration/integration-top-banner/integration-top-banner.component.mjs +6 -6
  13. package/esm2022/lib/public/components/resource-integration/resource-integration.component.mjs +13 -13
  14. package/esm2022/lib/public/components/resource-post/related-resources/related-resources.component.mjs +8 -8
  15. package/esm2022/lib/public/components/resource-post/related-resources/resource-cards/resource-cards.component.mjs +8 -8
  16. package/esm2022/lib/public/components/resource-post/resource-post-details/resource-post-details.component.mjs +3 -27
  17. package/esm2022/lib/public/components/resource-post/resource-post.component.mjs +7 -8
  18. package/esm2022/lib/public/components/resource-release-notes/resource-release-notes-top-banner/resource-release-notes-top-banner.component.mjs +6 -6
  19. package/esm2022/lib/public/components/resource-release-notes/resource-release-notes.component.mjs +6 -6
  20. package/esm2022/lib/public/components/resource-top-banner-edit/resource-top-banner-edit.component.mjs +3 -3
  21. package/esm2022/lib/public/components/resource-vault/resource-vault.component.mjs +8 -8
  22. package/esm2022/lib/public/components/resource-videos/resource-video-cards/resource-video-cards.component.mjs +18 -12
  23. package/esm2022/lib/public/components/resource-videos/resource-videos-top-banner/resource-videos-top-banner.component.mjs +6 -6
  24. package/esm2022/lib/public/components/resource-videos/resource-videos.component.mjs +6 -6
  25. package/esm2022/lib/public/components/resource-webinars/replay-event-cards/replay-event-cards.component.mjs +8 -8
  26. package/esm2022/lib/public/components/resource-webinars/resource-webinars.component.mjs +9 -9
  27. package/esm2022/lib/public/components/resource-webinars/upcoming-event-cards/upcoming-event-cards.component.mjs +21 -14
  28. package/esm2022/lib/public/components/resources/resource-tags/resource-tags.component.mjs +3 -3
  29. package/esm2022/lib/public/components/resources/resources.component.mjs +21 -18
  30. package/esm2022/lib/public/components/resources/vault-section/vault-section.component.mjs +5 -5
  31. package/esm2022/lib/public/components/resources-hub/resources-hub.component.mjs +12 -11
  32. package/esm2022/lib/public/components/testimonial-card/testimonial-card.component.mjs +10 -9
  33. package/esm2022/lib/public/components/white-papers/white-papers-top-banner/white-papers-top-banner.component.mjs +6 -6
  34. package/esm2022/lib/public/components/white-papers/white-papers.component.mjs +6 -6
  35. package/esm2022/lib/public/modules/blogs/resource-blogs.module.mjs +30 -0
  36. package/esm2022/lib/public/modules/case-studies/resource-case-studies.module.mjs +35 -0
  37. package/esm2022/lib/public/modules/events/resource-events.module.mjs +30 -0
  38. package/esm2022/lib/public/modules/hub/resource-hub.module.mjs +29 -0
  39. package/esm2022/lib/public/modules/integrations/resource-integrations.module.mjs +30 -0
  40. package/esm2022/lib/public/modules/post/resource-post.module.mjs +32 -0
  41. package/esm2022/lib/public/modules/release-notes/resource-release-notes.module.mjs +30 -0
  42. package/esm2022/lib/public/modules/root/resource-root-shared.module.mjs +61 -0
  43. package/esm2022/lib/public/modules/root/resource-root.module.mjs +32 -0
  44. package/esm2022/lib/public/modules/videos/resource-videos.module.mjs +30 -0
  45. package/esm2022/lib/public/modules/white-papers/resource-white-papers.module.mjs +31 -0
  46. package/esm2022/lib/public/resource-public.module.mjs +5 -175
  47. package/esm2022/lib/public/resource-public.routing.module.mjs +13 -62
  48. package/esm2022/lib/public/shared/resource-cards.module.mjs +116 -0
  49. package/esm2022/lib/public/shared/resource-edit.module.mjs +64 -0
  50. package/esm2022/lib/public/shared/resource-shared.module.mjs +116 -0
  51. package/esm2022/lib/shared/resource-modal.interface.mjs +2 -0
  52. package/fesm2022/posiwise-resource-module-base-top-banner.component-DFT3ZpJE.mjs +111 -0
  53. package/fesm2022/posiwise-resource-module-base-top-banner.component-DFT3ZpJE.mjs.map +1 -0
  54. package/fesm2022/posiwise-resource-module-posiwise-resource-module-D953ymF3.mjs +2311 -0
  55. package/fesm2022/posiwise-resource-module-posiwise-resource-module-D953ymF3.mjs.map +1 -0
  56. package/fesm2022/posiwise-resource-module-resource-blogs.module-Dpg-VGXf.mjs +91 -0
  57. package/fesm2022/posiwise-resource-module-resource-blogs.module-Dpg-VGXf.mjs.map +1 -0
  58. package/fesm2022/posiwise-resource-module-resource-case-studies.module-Bxfa0c61.mjs +127 -0
  59. package/fesm2022/posiwise-resource-module-resource-case-studies.module-Bxfa0c61.mjs.map +1 -0
  60. package/fesm2022/posiwise-resource-module-resource-events.module-CNKoXu2J.mjs +245 -0
  61. package/fesm2022/posiwise-resource-module-resource-events.module-CNKoXu2J.mjs.map +1 -0
  62. package/fesm2022/posiwise-resource-module-resource-hub.module-ggk9jRt9.mjs +249 -0
  63. package/fesm2022/posiwise-resource-module-resource-hub.module-ggk9jRt9.mjs.map +1 -0
  64. package/fesm2022/posiwise-resource-module-resource-integrations.module-vGdvpS64.mjs +286 -0
  65. package/fesm2022/posiwise-resource-module-resource-integrations.module-vGdvpS64.mjs.map +1 -0
  66. package/fesm2022/posiwise-resource-module-resource-post.module-RkJpZSPU.mjs +318 -0
  67. package/fesm2022/posiwise-resource-module-resource-post.module-RkJpZSPU.mjs.map +1 -0
  68. package/fesm2022/posiwise-resource-module-resource-release-notes.module-DKu39Lgo.mjs +124 -0
  69. package/fesm2022/posiwise-resource-module-resource-release-notes.module-DKu39Lgo.mjs.map +1 -0
  70. package/fesm2022/posiwise-resource-module-resource-root.module-CItOAAUj.mjs +403 -0
  71. package/fesm2022/posiwise-resource-module-resource-root.module-CItOAAUj.mjs.map +1 -0
  72. package/fesm2022/posiwise-resource-module-resource-videos.module-CuXWTy8y.mjs +91 -0
  73. package/fesm2022/posiwise-resource-module-resource-videos.module-CuXWTy8y.mjs.map +1 -0
  74. package/fesm2022/posiwise-resource-module-resource-white-papers.module-BJe9cvpS.mjs +92 -0
  75. package/fesm2022/posiwise-resource-module-resource-white-papers.module-BJe9cvpS.mjs.map +1 -0
  76. package/fesm2022/posiwise-resource-module.mjs +32 -3174
  77. package/fesm2022/posiwise-resource-module.mjs.map +1 -1
  78. package/index.d.ts +17 -2
  79. package/lib/public/components/reslease-note-card/release-note-card.component.d.ts +2 -1
  80. package/lib/public/components/resource-case-studies/case-studies-cards/case-studies-cards.component.d.ts +4 -2
  81. package/lib/public/components/resource-contact-us/resource-contact-us.component.d.ts +126 -0
  82. package/lib/public/components/resource-contact-us/resource-contact-us.module.d.ts +23 -0
  83. package/lib/public/components/resource-edit-card-lazy/resource-edit-card-lazy.component.d.ts +19 -0
  84. package/lib/public/components/resource-post/resource-post-details/resource-post-details.component.d.ts +0 -2
  85. package/lib/public/components/resource-videos/resource-video-cards/resource-video-cards.component.d.ts +4 -2
  86. package/lib/public/components/resource-webinars/upcoming-event-cards/upcoming-event-cards.component.d.ts +4 -2
  87. package/lib/public/components/resources/resources.component.d.ts +3 -2
  88. package/lib/public/modules/blogs/resource-blogs.module.d.ts +10 -0
  89. package/lib/public/modules/case-studies/resource-case-studies.module.d.ts +10 -0
  90. package/lib/public/modules/events/resource-events.module.d.ts +10 -0
  91. package/lib/public/modules/hub/resource-hub.module.d.ts +9 -0
  92. package/lib/public/modules/integrations/resource-integrations.module.d.ts +10 -0
  93. package/lib/public/modules/post/resource-post.module.d.ts +11 -0
  94. package/lib/public/modules/release-notes/resource-release-notes.module.d.ts +10 -0
  95. package/lib/public/modules/root/resource-root-shared.module.d.ts +17 -0
  96. package/lib/public/modules/root/resource-root.module.d.ts +11 -0
  97. package/lib/public/modules/videos/resource-videos.module.d.ts +10 -0
  98. package/lib/public/modules/white-papers/resource-white-papers.module.d.ts +10 -0
  99. package/lib/public/resource-public.module.d.ts +2 -51
  100. package/lib/public/shared/resource-cards.module.d.ts +32 -0
  101. package/lib/public/shared/resource-edit.module.d.ts +22 -0
  102. package/lib/public/shared/resource-shared.module.d.ts +19 -0
  103. package/lib/shared/resource-modal.interface.d.ts +6 -0
  104. package/package.json +1 -1
  105. package/esm2022/lib/public/components/resource-card-list/resource-card-list.component.mjs +0 -22
  106. package/esm2022/lib/public/components/resources-read/resources-read.component.mjs +0 -125
  107. package/lib/public/components/resource-card-list/resource-card-list.component.d.ts +0 -8
  108. package/lib/public/components/resources-read/resources-read.component.d.ts +0 -43
@@ -0,0 +1,2311 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Injectable, NgModule, CUSTOM_ELEMENTS_SCHEMA, Component, ChangeDetectionStrategy, Inject, ViewChild, Input, EventEmitter, ViewContainerRef, Output } from '@angular/core';
3
+ import * as i2 from '@posiwise/common-services';
4
+ import { ValidationService } from '@posiwise/common-services';
5
+ import { HelperService } from '@posiwise/helper-service';
6
+ import * as i1 from '@angular/router';
7
+ import { RouterModule } from '@angular/router';
8
+ import * as i9 from '@angular/cdk/drag-drop';
9
+ import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
10
+ import * as i3$2 from '@angular/common';
11
+ import { DOCUMENT, CommonModule } from '@angular/common';
12
+ import * as i1$1 from '@angular/forms';
13
+ import { Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
14
+ import * as i3$1 from '@angular/platform-browser';
15
+ import * as i5 from '@posiwise/admin-module-utils';
16
+ import { AdminModuleUtilsModule } from '@posiwise/admin-module-utils';
17
+ import { AppBaseComponent } from '@posiwise/app-base-component';
18
+ import * as i6 from '@posiwise/shared-components';
19
+ import { ProfileImageCropperModule, FieldErrorDisplayModule, ResourceSharedComponentsModule } from '@posiwise/shared-components';
20
+ import * as i3 from '@posiwise/smart-crm-shared';
21
+ import { StatusCodes } from 'http-status-codes';
22
+ import Swal from 'sweetalert2';
23
+ import * as i2$1 from '@ng-bootstrap/ng-bootstrap';
24
+ import { NgbModalModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
25
+ import * as i8 from '@posiwise/directives';
26
+ import { DirectivesModule } from '@posiwise/directives';
27
+ import * as i11 from 'ngx-captcha';
28
+ import { NgxCaptchaModule } from 'ngx-captcha';
29
+ import * as i12 from 'primeng/dropdown';
30
+ import { DropdownModule } from 'primeng/dropdown';
31
+ import * as i10 from '@jsverse/transloco';
32
+ import { TranslocoModule } from '@jsverse/transloco';
33
+ import { CoreTranslocoModule } from '@posiwise/core-transloco';
34
+ import { PipesModule } from '@posiwise/pipes';
35
+ import { InputTextModule } from 'primeng/inputtext';
36
+ import { InputTextareaModule } from 'primeng/inputtextarea';
37
+ import { Subject } from 'rxjs';
38
+ import { PaginatorModule } from 'primeng/paginator';
39
+ import * as i7 from 'primeng/progressspinner';
40
+ import * as i10$1 from 'ngx-quill';
41
+ import { QuillModule } from 'ngx-quill';
42
+ import * as i11$1 from 'ngx-ui-switch';
43
+ import { UiSwitchModule } from 'ngx-ui-switch';
44
+ import * as i7$1 from 'primeng/autocomplete';
45
+ import { AutoCompleteModule } from 'primeng/autocomplete';
46
+ import * as i6$1 from 'primeng/calendar';
47
+ import { CalendarModule } from 'primeng/calendar';
48
+ import moment from 'moment';
49
+
50
+ class ResourceService {
51
+ constructor(api) {
52
+ this.api = api;
53
+ this.resource = '/posts';
54
+ this.comments = '/comments';
55
+ }
56
+ getPublicPosts(master_subscription_id, page, pageSize, search, tagCategoryIds, tagIds) {
57
+ const params = {
58
+ page,
59
+ page_size: pageSize,
60
+ search: search,
61
+ master_subscription_id
62
+ };
63
+ if (tagCategoryIds) {
64
+ params['tag_category_ids'] = tagCategoryIds;
65
+ }
66
+ if (tagIds) {
67
+ params['tag_ids'] = tagIds;
68
+ }
69
+ return this.api.getWithParams(`${this.resource}/get_all`, {
70
+ ...params
71
+ });
72
+ }
73
+ getAdminPosts(subscriptionId, paging) {
74
+ return this.api.getWithParams(`${this.resource}/admin_get_all`, {
75
+ ...HelperService.getPagingParams(paging),
76
+ subscription_id: subscriptionId
77
+ });
78
+ }
79
+ addPost(post) {
80
+ const formData = new FormData();
81
+ // eslint-disable-next-line no-restricted-syntax
82
+ for (const key in post) {
83
+ if (key in post) {
84
+ formData.append(key, post[key]);
85
+ }
86
+ }
87
+ return this.api.post(this.resource, formData);
88
+ }
89
+ getPostBySlug(slug) {
90
+ return this.api.get(`${this.resource}/${slug}`);
91
+ }
92
+ deletePost(id) {
93
+ return this.api.delete(`${this.resource}/${id}`);
94
+ }
95
+ updatePost(post, id) {
96
+ const formData = new FormData();
97
+ // eslint-disable-next-line no-restricted-syntax
98
+ for (const key in post) {
99
+ if (key in post) {
100
+ formData.append(key, post[key]);
101
+ }
102
+ }
103
+ return this.api.put(`${this.resource}/${id}`, formData);
104
+ }
105
+ getComments() {
106
+ return this.api.get(`${this.comments}/get_all`);
107
+ }
108
+ postComments(post) {
109
+ return this.api.post(this.comments, post);
110
+ }
111
+ getResourceInsight(subscription_id, starting_at, ending_at) {
112
+ return this.api.getWithParams(`/admin/posts_analytics?type=views&subscription_id=${subscription_id}`, { starting_at, ending_at });
113
+ }
114
+ getResourcePostsInsight(id) {
115
+ return this.api.get(`${this.resource}/${id}/insights`);
116
+ }
117
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceService, deps: [{ token: i2.MainApiHttpService }], target: i0.ɵɵFactoryTarget.Injectable }); }
118
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceService }); }
119
+ }
120
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceService, decorators: [{
121
+ type: Injectable
122
+ }], ctorParameters: () => [{ type: i2.MainApiHttpService }] });
123
+
124
+ // Lazy loaded routes - each route now loads its own module with only the components it needs
125
+ const routes = [
126
+ {
127
+ path: '',
128
+ pathMatch: 'full',
129
+ loadChildren: () => import('./posiwise-resource-module-resource-root.module-CItOAAUj.mjs').then(m => m.ResourceRootModule)
130
+ },
131
+ {
132
+ path: 'hub',
133
+ loadChildren: () => import('./posiwise-resource-module-resource-hub.module-ggk9jRt9.mjs').then(m => m.ResourceHubModule)
134
+ },
135
+ {
136
+ path: 'blogs',
137
+ loadChildren: () => import('./posiwise-resource-module-resource-blogs.module-Dpg-VGXf.mjs').then(m => m.ResourceBlogsModule)
138
+ },
139
+ {
140
+ path: 'videos',
141
+ loadChildren: () => import('./posiwise-resource-module-resource-videos.module-CuXWTy8y.mjs').then(m => m.ResourceVideosModule)
142
+ },
143
+ {
144
+ path: 'integrations',
145
+ loadChildren: () => import('./posiwise-resource-module-resource-integrations.module-vGdvpS64.mjs').then(m => m.ResourceIntegrationsModule)
146
+ },
147
+ {
148
+ path: 'release-notes',
149
+ loadChildren: () => import('./posiwise-resource-module-resource-release-notes.module-DKu39Lgo.mjs').then(m => m.ResourceReleaseNotesModule)
150
+ },
151
+ {
152
+ path: 'events',
153
+ loadChildren: () => import('./posiwise-resource-module-resource-events.module-CNKoXu2J.mjs').then(m => m.ResourceEventsModule)
154
+ },
155
+ {
156
+ path: 'white-papers',
157
+ loadChildren: () => import('./posiwise-resource-module-resource-white-papers.module-BJe9cvpS.mjs').then(m => m.ResourceWhitePapersModule)
158
+ },
159
+ {
160
+ path: 'case-studies',
161
+ loadChildren: () => import('./posiwise-resource-module-resource-case-studies.module-Bxfa0c61.mjs').then(m => m.ResourceCaseStudiesModule)
162
+ },
163
+ {
164
+ path: 'view/:slug',
165
+ loadChildren: () => import('./posiwise-resource-module-resource-post.module-RkJpZSPU.mjs').then(m => m.ResourcePostModule)
166
+ }
167
+ ];
168
+ class BlogPublicRoutingModule {
169
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: BlogPublicRoutingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
170
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.11", ngImport: i0, type: BlogPublicRoutingModule, imports: [i1.RouterModule], exports: [RouterModule] }); }
171
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: BlogPublicRoutingModule, imports: [RouterModule.forChild(routes), RouterModule] }); }
172
+ }
173
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: BlogPublicRoutingModule, decorators: [{
174
+ type: NgModule,
175
+ args: [{
176
+ imports: [RouterModule.forChild(routes)],
177
+ exports: [RouterModule]
178
+ }]
179
+ }] });
180
+
181
+ class ResourcePublicModule {
182
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourcePublicModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
183
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.11", ngImport: i0, type: ResourcePublicModule, imports: [BlogPublicRoutingModule] }); }
184
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourcePublicModule, providers: [ResourceService], imports: [BlogPublicRoutingModule] }); }
185
+ }
186
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourcePublicModule, decorators: [{
187
+ type: NgModule,
188
+ args: [{
189
+ imports: [BlogPublicRoutingModule],
190
+ providers: [ResourceService],
191
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
192
+ }]
193
+ }] });
194
+
195
+ class ResourceModule {
196
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
197
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.11", ngImport: i0, type: ResourceModule, imports: [ResourcePublicModule] }); }
198
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceModule, imports: [ResourcePublicModule] }); }
199
+ }
200
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceModule, decorators: [{
201
+ type: NgModule,
202
+ args: [{
203
+ imports: [ResourcePublicModule]
204
+ }]
205
+ }] });
206
+
207
+ class Trial4ContactUsComponent extends AppBaseComponent {
208
+ openQuestionsEditModal() {
209
+ this.editingQuestions = JSON.parse(JSON.stringify(this.editingQuestions ?? []));
210
+ this.modalService.open(this.questionsEditModal, { centered: true, size: 'lg' });
211
+ }
212
+ constructor(fb, authService, crmService, sanitizer, adminService, injector, abTestService, modalService, cdr, document) {
213
+ super(injector);
214
+ this.fb = fb;
215
+ this.authService = authService;
216
+ this.crmService = crmService;
217
+ this.sanitizer = sanitizer;
218
+ this.adminService = adminService;
219
+ this.abTestService = abTestService;
220
+ this.modalService = modalService;
221
+ this.cdr = cdr;
222
+ this.document = document;
223
+ this.editingQuestions = [];
224
+ this.isFooterVisible = false;
225
+ this.recaptcha = null;
226
+ this.subscriptionId = this.appConfig.crm.subscription_id;
227
+ this.sourceId = this.appConfig.crm.source_id;
228
+ this.masterSubscriptionId = this.appConfig.master_subscription.subscription_id;
229
+ this.canEditResourcesValue = false;
230
+ this.logo = this.appConfig?.company?.logos?.main_contrast?.url;
231
+ this.trialBgImage2 = this.appConfig?.signup_config.trial?.image_bg2?.url;
232
+ this.tosId = this.appConfig?.main_tos_id;
233
+ this.description = this.appConfig.company.description;
234
+ this.email = this.appConfig.company.email;
235
+ this.companyName = this.appConfig.company.name;
236
+ this.street = this.appConfig.company.street;
237
+ this.questions = this.appConfig?.pages_config?.contact_us?.questions;
238
+ this.hubspot = this.appConfig?.pages_config?.contact_us?.hubspot;
239
+ this.footerLinks = this.appConfig?.pages_config?.footer_links?.items;
240
+ this.footerLinksData = this.appConfig?.pages_config?.footer_links;
241
+ this.youtubeUrl = this.appConfig.social?.youtube_url;
242
+ this.linkedInUrl = this.appConfig.social?.linkedin_url;
243
+ this.domainId = this.appConfig.domain_id;
244
+ this.editingEmail = this.email;
245
+ this.isEditingEmail = false;
246
+ this.submitted = false;
247
+ this.isCaptchaVerified = false;
248
+ this.isEmailValid = true;
249
+ this.isEditingStreet = false;
250
+ this.editingFooterLinks = {
251
+ items: []
252
+ };
253
+ this.captchaKeyV2 = this.appConfig.integrations.captcha_key_V2;
254
+ this.contactUsForm();
255
+ }
256
+ ngOnInit() {
257
+ setTimeout(() => (this.isHubspotReady = true), 2000);
258
+ if (this.userLoggedIn) {
259
+ this.localStorage.getItem$('product').subscribe(res => {
260
+ const data = res ? JSON.parse(res) : null;
261
+ this.id = data?.subscriptionId;
262
+ });
263
+ }
264
+ this.previewData = {
265
+ url: this.logo,
266
+ name: 'logo_main_contrast.png'
267
+ };
268
+ this.editingStreet = this.street;
269
+ if (Array.isArray(this.appConfig.pages_config?.ab_tests)) {
270
+ this.abTests = this.appConfig.pages_config.ab_tests.find(test => test.description === 'contact-us');
271
+ this.microserviceName = this.abTests?.microservice_name;
272
+ this.experimentName = this.abTests?.experiment_name;
273
+ this.shardName = this.abTests?.db_shard;
274
+ }
275
+ const footerItem = this.getFooterHubspotForm();
276
+ if (footerItem?.div) {
277
+ // NOSONAR: Trusted HTML content is handled safely here
278
+ this.hubspotHtml = this.sanitizer.bypassSecurityTrustHtml(footerItem.div); // NOSONAR
279
+ }
280
+ this.editingQuestions = this.questions;
281
+ this.question = this.questions?.[0]?.question;
282
+ this.psaOptions = [
283
+ { label: 'Select PSA', value: '' },
284
+ ...(this.questions?.[0]?.options ?? [])
285
+ .filter(q => q.option?.trim())
286
+ .map(q => ({
287
+ label: q.option,
288
+ value: q.option
289
+ }))
290
+ ];
291
+ }
292
+ ngOnChanges(changes) {
293
+ if (changes['user'] || changes['userLoggedIn']) {
294
+ if (this.userLoggedIn && this.user) {
295
+ this.updateCanEditResourcesValue();
296
+ }
297
+ }
298
+ }
299
+ openLogoEditModal() {
300
+ this.modalService.open(this.logoModal, {
301
+ centered: true,
302
+ size: 'md'
303
+ });
304
+ }
305
+ onSaveFile(event) {
306
+ const formData = new FormData();
307
+ const data = { subscription_id: this.subscriptionId };
308
+ if (event.file instanceof File) {
309
+ data[event.name] = event.file;
310
+ }
311
+ else if (event.file === null) {
312
+ data[`remove_${event.name}`] = true;
313
+ }
314
+ for (const key in data) {
315
+ formData.append(key, data[key]);
316
+ }
317
+ this.adminService.updateDomainConfig(this.domainId, formData).subscribe(() => {
318
+ if (event.file) {
319
+ this.logo = URL.createObjectURL(event.file);
320
+ this.modalService.dismissAll();
321
+ }
322
+ this.toast.success(event.file ? 'Logo updated' : 'Logo removed');
323
+ });
324
+ }
325
+ saveQuestions(modal) {
326
+ const updateData = {
327
+ contact_us: {
328
+ ...this.appConfig.pages_config?.contact_us,
329
+ questions: this.editingQuestions
330
+ },
331
+ subscription_id: this.id
332
+ };
333
+ this.adminService.updateDomainConfig(this.domainId, updateData).subscribe(() => {
334
+ this.questions = this.editingQuestions;
335
+ this.toast.success('Questions updated');
336
+ this.question = this.editingQuestions?.[0]?.question;
337
+ if (this.editingQuestions?.[0]?.options?.length > 0) {
338
+ this.psaOptions = [
339
+ { label: 'Select PSA', value: '' },
340
+ ...(this.questions?.[0]?.options ?? [])
341
+ .filter(q => q.option?.trim())
342
+ .map(q => ({
343
+ label: q.option,
344
+ value: q.option
345
+ }))
346
+ ];
347
+ }
348
+ else {
349
+ this.psaOptions = [];
350
+ }
351
+ modal.close();
352
+ });
353
+ }
354
+ addNewQuestion() {
355
+ this.editingQuestions.push({ question: '', options: [] });
356
+ }
357
+ addQuestionOption(qIndex) {
358
+ this.editingQuestions[qIndex].options.push({ option: '' });
359
+ }
360
+ removeQuestionOption(qIndex, optIndex) {
361
+ this.editingQuestions[qIndex].options.splice(optIndex, 1);
362
+ }
363
+ dropQuestions(event) {
364
+ moveItemInArray(this.editingQuestions, event.previousIndex, event.currentIndex);
365
+ }
366
+ dropQuestionOptions(qIndex, event) {
367
+ moveItemInArray(this.editingQuestions[qIndex].options, event.previousIndex, event.currentIndex);
368
+ }
369
+ openSocialEditModal() {
370
+ this.editingYoutubeUrl = this.youtubeUrl;
371
+ this.editingLinkedInUrl = this.linkedInUrl;
372
+ this.editingCompanyName = this.companyName;
373
+ this.modalService.open(this.socialEditModal, { centered: true, size: 'lg' });
374
+ }
375
+ saveSocialLinks(modal) {
376
+ const updateData = {
377
+ youtube_url: this.editingYoutubeUrl,
378
+ linkedin_url: this.editingLinkedInUrl,
379
+ company_name: this.editingCompanyName,
380
+ subscription_id: this.id
381
+ };
382
+ this.adminService.updateDomainConfig(this.domainId, updateData).subscribe(() => {
383
+ this.youtubeUrl = this.editingYoutubeUrl;
384
+ this.linkedInUrl = this.editingLinkedInUrl;
385
+ this.companyName = this.editingCompanyName;
386
+ this.toast.success('Social links and company name updated');
387
+ modal.close();
388
+ });
389
+ }
390
+ hasValidOptions() {
391
+ return this.questions?.[0]?.options?.some(opt => opt.option?.trim());
392
+ }
393
+ ngAfterViewInit() {
394
+ this.watchIframeHeightChange();
395
+ this.observer = new IntersectionObserver(([entry]) => {
396
+ if (entry.isIntersecting) {
397
+ this.isFooterVisible = true;
398
+ this.cdr.detectChanges();
399
+ this.observer?.disconnect();
400
+ }
401
+ }, { threshold: 0.1 });
402
+ this.observer.observe(this.footerSection.nativeElement);
403
+ }
404
+ openEditFooterLinksModal(content) {
405
+ this.footerLinksData = this.footerLinksData ?? {};
406
+ this.footerLinksData.items = this.footerLinksData.items ?? [];
407
+ this.editingFooterLinks = JSON.parse(JSON.stringify(this.footerLinksData));
408
+ this.modalService.open(content, {
409
+ size: 'lg',
410
+ centered: true,
411
+ windowClass: 'modal-holder'
412
+ });
413
+ }
414
+ watchIframeHeightChange() {
415
+ const iframe = this.document.querySelector('.hubspot-container');
416
+ if (!iframe)
417
+ return;
418
+ const interval = setInterval(() => {
419
+ const newHeight = iframe['offsetHeight'];
420
+ if (newHeight === 250) {
421
+ clearInterval(interval);
422
+ this.callAbTestFinish();
423
+ }
424
+ }, 300);
425
+ }
426
+ // New method to handle Hubspot content loading
427
+ onHubspotLoad(event) {
428
+ const container = event.target;
429
+ container.classList.add('content-loaded');
430
+ // Optional: Trigger layout recalculation
431
+ setTimeout(() => {
432
+ window.dispatchEvent(new Event('resize'));
433
+ }, 100);
434
+ }
435
+ callAbTestFinish() {
436
+ if (this.experimentName && this.microserviceName) {
437
+ this.abTestService
438
+ .finishABExperiment(this.experimentName, this.microserviceName)
439
+ .subscribe(() => {
440
+ this.modalService.open(this.content, {
441
+ centered: true,
442
+ windowClass: 'modal-holder'
443
+ });
444
+ });
445
+ }
446
+ }
447
+ contactUsForm() {
448
+ this.form = this.fb.group({
449
+ first_name: ['', Validators.required],
450
+ last_name: [''],
451
+ company: [''],
452
+ psa: [''],
453
+ enquiry: ['', Validators.required],
454
+ email: ['', Validators.required]
455
+ });
456
+ }
457
+ onSubmit() {
458
+ this.submitted = true;
459
+ if (this.form.valid) {
460
+ this.isCaptchaVerified = true;
461
+ this.submitted = false;
462
+ }
463
+ }
464
+ handleSuccess(token) {
465
+ if (token) {
466
+ this.authService.validateReCaptcha(token).subscribe((isSuccess) => {
467
+ if (isSuccess && this.form.valid) {
468
+ const data = { ...this.form.getRawValue() };
469
+ const formattedEnquiry = `${data.enquiry}; Question: ${this.question}; Answer: ${data.psa}`;
470
+ const postData = {
471
+ first_name: `${data.first_name}`,
472
+ last_name: `${data.first_name}`,
473
+ company: `${data.first_name}`,
474
+ email: `${data.email}`,
475
+ enquiry: this.psaOptions.length ? formattedEnquiry : `${data.enquiry}`,
476
+ psa: data.psa,
477
+ subscription_id: this.subscriptionId,
478
+ crm_source_id: this.sourceId,
479
+ master_subscription_id: this.masterSubscriptionId,
480
+ notify_user: false,
481
+ is_manual: false
482
+ };
483
+ this.crmService.postCrmLead(this.subscriptionId, postData).subscribe(resp => {
484
+ // example of snippet to close the experiment and track in GA
485
+ if (resp?.status === StatusCodes.OK) {
486
+ this.googleAnalyticsService.sendEvent('new-lead-registration', // category, eg: videos
487
+ 'subscribe-success', // action, eg: Play
488
+ 'coming-soon-three', // label, eg: Chappy
489
+ 1 // value, eg: 10
490
+ );
491
+ if (this.experimentName && this.microserviceName) {
492
+ this.abTestService
493
+ .finishABExperiment(this.experimentName, this.microserviceName)
494
+ .subscribe(() => {
495
+ this.modalService.open(this.content, {
496
+ centered: true,
497
+ windowClass: 'modal-holder'
498
+ });
499
+ });
500
+ }
501
+ else {
502
+ Swal.fire(resp.message);
503
+ }
504
+ }
505
+ this.form.reset();
506
+ this.isCaptchaVerified = false;
507
+ });
508
+ }
509
+ });
510
+ }
511
+ }
512
+ scrollToTop() {
513
+ this.document.documentElement.scrollTop = 0;
514
+ }
515
+ getFooterHubspotForm() {
516
+ if (!this.hubspot?.length) {
517
+ return null;
518
+ }
519
+ return this.hubspot.find(item => item.position === 'footer') ?? null;
520
+ }
521
+ navigateToBookMeeting() {
522
+ window.open('https://calendly.com/cloudolive', '_blank', 'noreferrer noopener');
523
+ }
524
+ validateEmail() {
525
+ const email = this.form.get('email').value;
526
+ if (email) {
527
+ this.isEmailValid = ValidationService.email(email);
528
+ }
529
+ else {
530
+ this.isEmailValid = true;
531
+ }
532
+ }
533
+ addFooterLink() {
534
+ this.editingFooterLinks.items.push({
535
+ title: '',
536
+ path: '',
537
+ subtitles: []
538
+ });
539
+ }
540
+ removeFooterLink(index) {
541
+ this.editingFooterLinks.items.splice(index, 1);
542
+ }
543
+ addSubtitle(footerIndex) {
544
+ this.editingFooterLinks.items[footerIndex].subtitles.push({
545
+ title: '',
546
+ path: ''
547
+ });
548
+ }
549
+ removeSubtitle(footerIndex, subtitleIndex) {
550
+ this.editingFooterLinks.items[footerIndex].subtitles.splice(subtitleIndex, 1);
551
+ }
552
+ dropFooterLinks(event) {
553
+ moveItemInArray(this.editingFooterLinks.items, event.previousIndex, event.currentIndex);
554
+ }
555
+ dropSubtitles(footerIndex, event) {
556
+ moveItemInArray(this.editingFooterLinks.items[footerIndex].subtitles, event.previousIndex, event.currentIndex);
557
+ }
558
+ saveFooterLinks(modal) {
559
+ const updatedConfig = {
560
+ footer_links: this.editingFooterLinks,
561
+ subscription_id: this.id
562
+ };
563
+ this.adminService
564
+ .updateDomainConfig(this.appConfig?.domain_id, updatedConfig)
565
+ .subscribe(() => {
566
+ this.toast.success('Footer links updated');
567
+ this.footerLinks = [...this.editingFooterLinks.items];
568
+ this.footerLinksData = { ...this.editingFooterLinks };
569
+ modal.close();
570
+ });
571
+ }
572
+ saveEmail() {
573
+ this.email = this.editingEmail;
574
+ this.adminService
575
+ .updateDomainConfig(this.appConfig?.domain_id, {
576
+ company_email: this.editingEmail,
577
+ subscription_id: this.id
578
+ })
579
+ .subscribe(() => {
580
+ this.toast.success('Email updated');
581
+ this.isEditingEmail = false;
582
+ });
583
+ }
584
+ saveStreet() {
585
+ this.adminService
586
+ .updateDomainConfig(this.appConfig?.domain_id, {
587
+ company_address: this.editingStreet,
588
+ subscription_id: this.id
589
+ })
590
+ .subscribe(() => {
591
+ this.toast.success('Street updated');
592
+ this.street = this.editingStreet;
593
+ this.isEditingStreet = false;
594
+ });
595
+ }
596
+ cancelStreet() {
597
+ this.editingStreet = this.street;
598
+ this.isEditingStreet = false;
599
+ }
600
+ openHubspotEditModal(footerItem) {
601
+ this.editingHubspotHtml = footerItem.div;
602
+ this.editingHubspotId = footerItem.id;
603
+ this.modalService.open(this.hubspotEditModal, { centered: true, size: 'lg' });
604
+ }
605
+ saveHubspotHtml(modal) {
606
+ const updatedConfig = {
607
+ contact_us: {
608
+ ...this.appConfig?.pages_config?.contact_us,
609
+ hubspot: [
610
+ {
611
+ id: '7423639',
612
+ position: 'footer',
613
+ div: this.editingHubspotHtml
614
+ }
615
+ ]
616
+ },
617
+ subscription_id: this.id
618
+ };
619
+ this.adminService
620
+ .updateDomainConfig(this.appConfig?.domain_id, updatedConfig)
621
+ .subscribe(() => {
622
+ // NOSONAR: Trusted HTML content is handled safely here
623
+ this.hubspotHtml = this.sanitizer.bypassSecurityTrustHtml(this.editingHubspotHtml); // NOSONAR
624
+ this.toast.success('Hubspot Embed updated');
625
+ modal.close();
626
+ });
627
+ }
628
+ updateCanEditResourcesValue() {
629
+ this.canEditResourcesValue = HelperService.canEditResources(this.user, this.userLoggedIn, this.permissionService);
630
+ }
631
+ canEditResources() {
632
+ return this.canEditResourcesValue;
633
+ }
634
+ ngOnDestroy() {
635
+ this.observer?.disconnect();
636
+ }
637
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: Trial4ContactUsComponent, deps: [{ token: i1$1.UntypedFormBuilder }, { token: i2.AuthService }, { token: i3.CrmService }, { token: i3$1.DomSanitizer }, { token: i5.AdminService }, { token: i0.Injector }, { token: i2.AbTestService }, { token: i2$1.NgbModal }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
638
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: Trial4ContactUsComponent, selector: "pw-trial-4-contact-us", inputs: { subscriptionId: "subscriptionId", sourceId: "sourceId", masterSubscriptionId: "masterSubscriptionId", experimentName: "experimentName", microserviceName: "microserviceName", shardName: "shardName", user: "user", userLoggedIn: "userLoggedIn" }, viewQueries: [{ propertyName: "footerSection", first: true, predicate: ["footerSection"], descendants: true, static: true }, { propertyName: "content", first: true, predicate: ["bookMeeting"], descendants: true, static: true }, { propertyName: "editFooterLinksModal", first: true, predicate: ["editFooterLinksModal"], descendants: true }, { propertyName: "logoModal", first: true, predicate: ["logoModal"], descendants: true }, { propertyName: "logoUploader", first: true, predicate: ["logoUploader"], descendants: true }, { propertyName: "hubspotEditModal", first: true, predicate: ["hubspotEditModal"], descendants: true }, { propertyName: "socialEditModal", first: true, predicate: ["socialEditModal"], descendants: true }, { propertyName: "questionsEditModal", first: true, predicate: ["questionsEditModal"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<section #footerSection class=\"bg-black text-white py-5 footer-section\">\n <div class=\"container\" *ngIf=\"isFooterVisible\">\n <div class=\"row\">\n\n <!-- LEFT COLUMN -->\n <div class=\"col-md-6 mb-4 d-flex flex-column justify-content-between\" [ngClass]=\"{ 'site-column': getFooterHubspotForm() }\">\n <div>\n <h3 class=\"mb-4 d-flex align-items-center\">\n <span class=\"me-2 text-white\">Site Map:</span>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon cursor-pointer text-white ms-3\" (click)=\"openEditFooterLinksModal(editFooterLinksModal)\" (keydown.enter)=\"openEditFooterLinksModal(editFooterLinksModal)\" (keydown.space)=\"openEditFooterLinksModal(editFooterLinksModal)\" ngbTooltip=\"Edit Footer Links\"></i>\n </h3>\n <ul class=\"mt-4\">\n <li routerLink=\"/\"\n class=\"cursor-pointer user-info-label link-label\"> Home </li>\n <li *ngFor=\"let link of footerLinks\" [routerLink]=\"link?.path\"\n class=\"cursor-pointer user-info-label link-label mt-4\"><span *ngIf=\"link?.title\">{{link?.title}}</span> </li>\n <li routerLink=\"/login\"\n class=\"cursor-pointer user-info-label mt-4 link-label\"> Log in </li>\n <li [routerLink]=\"'/privacy-and-tos/' + tosId\"\n class=\"cursor-pointer user-info-label mt-4 link-label\"> Privacy statement </li>\n </ul>\n <p class=\"address-section email-section mb-4\">\n <span class=\"user-info-label\">Email: </span>\n <ng-container *ngIf=\"!isEditingEmail; else editEmail\">\n <span class=\"user-info\">{{ email }}</span>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon text-white cursor-pointer ms-3\" (click)=\"isEditingEmail = true\" (keydown.enter)=\"isEditingEmail = true\" (keydown.space)=\"isEditingEmail = true\"></i>\n </ng-container>\n\n <ng-template #editEmail>\n <input\n class=\"form-control d-inline w-auto\"\n [(ngModel)]=\"editingEmail\"\n />\n <button class=\"btn btn-sm btn-primary ms-2\" (click)=\"saveEmail()\">Save</button>\n <button class=\"btn btn-sm btn-secondary ms-2\" (click)=\"isEditingEmail = false\">Cancel</button>\n </ng-template>\n </p>\n <span class=\"email-section mt-3 address-text\">\n <span class=\"user-info-label\">\n Address:\n <i *ngIf=\"canEditResourcesValue\"\n class=\"fa fa-edit in-page-edit-icon cursor-pointer ms-2 text-white\"\n title=\"Edit Address\"\n (click)=\"isEditingStreet = true\"\n (keydown.enter)=\"isEditingStreet = true\"\n (keydown.space)=\"isEditingStreet = true\"></i>\n </span><br/>\n\n <ng-container *ngIf=\"!isEditingStreet; else editStreetBlock\">\n <span class=\"address-text user-info\">{{ street }}</span>\n </ng-container>\n\n <ng-template #editStreetBlock>\n <div class=\"d-flex align-items-center mt-3\">\n <input class=\"form-control form-control-sm\" [(ngModel)]=\"editingStreet\" />\n <button class=\"btn btn-sm btn-primary ms-2\" (click)=\"saveStreet()\">Save</button>\n <button class=\"btn btn-sm btn-secondary ms-2\" (click)=\"cancelStreet()\">Cancel</button>\n </div>\n </ng-template>\n\n </span>\n\n </div>\n <div class=\"d-flex\">\n <img [src]=\"logo\"\n alt=\"Company logo\"\n class=\"img-fluid mt-4 logo-image cursor-pointer\"\n width=\"160\"\n height=\"35\"\n (click)=\"scrollToTop()\"\n (keydown.enter)=\"scrollToTop()\"\n (keydown.space)=\"scrollToTop()\"\n title=\"Click to go to top of page\" />\n <i *ngIf=\"canEditResourcesValue\"\n class=\"fa fa-edit in-page-edit-icon fa-sm ms-3 cursor-pointer text-white align-self-center mt-3\"\n (click)=\"openLogoEditModal()\"\n (keydown.enter)=\"openLogoEditModal()\"\n (keydown.space)=\"openLogoEditModal()\"\n title=\"Edit Logo\"></i>\n </div>\n </div>\n\n <!-- RIGHT COLUMN -->\n <div class=\"col-md-6\" *ngIf=\"isFooterVisible\">\n <ng-container *ngIf=\"getFooterHubspotForm() as footerItem; else defaultForm\">\n <div class=\"d-flex\">\n <div\n *ngIf=\"isHubspotReady\"\n class=\"hubspot-container w-100 content-loaded\"\n [innerHTML]=\"hubspotHtml\"\n (load)=\"onHubspotLoad($event)\">\n </div>\n <i *ngIf=\"canEditResourcesValue\"\n class=\"fa fa-edit in-page-edit-icon text-white cursor-pointer\"\n (click)=\"openHubspotEditModal(footerItem)\"\n (keydown.enter)=\"openHubspotEditModal(footerItem)\"\n (keydown.space)=\"openHubspotEditModal(footerItem)\"\n title=\"Edit Hubspot Embed\"></i>\n </div>\n </ng-container>\n\n <ng-template #defaultForm>\n <div class=\"d-flex\">\n <h3 class=\"text-white mb-4\"> <span class=\"text-white\">Get in touch:</span></h3>\n <i *ngIf=\"canEditResourcesValue\"\n class=\"fa fa-edit in-page-edit-icon text-white cursor-pointer ms-3 mt-2\"\n (click)=\"openQuestionsEditModal()\"\n (keydown.enter)=\"openQuestionsEditModal()\"\n (keydown.space)=\"openQuestionsEditModal()\"\n title=\"Edit Questions\"></i>\n </div>\n <div class=\"contact-form\">\n <form [formGroup]=\"form\">\n <div class=\"mb-3\">\n <div class=\"email\">\n <div class=\"form-field\">\n <label for=\"email\">Email:</label>\n <div class=\"w-100\">\n <input type=\"text\"\n class=\"mb-1\"\n id=\"email\"\n formControlName=\"email\" />\n <pw-field-error-display [displayError]=\"\n !form.get('email').valid && (form.get('email').touched || submitted)\n \"\n errorMsg=\"Email is required\">\n </pw-field-error-display>\n </div>\n </div>\n <div class=\"form-field\">\n <label for=\"first_name\">First name:</label>\n <div class=\"w-100\">\n <input input type=\"text\"\n id=\"first_name\"\n formControlName=\"first_name\" />\n <pw-field-error-display [displayError]=\"\n !form.get('first_name').valid && (form.get('first_name').touched || submitted)\n \"\n errorMsg=\"First name is required\">\n </pw-field-error-display>\n </div>\n </div>\n <div class=\"form-field\">\n <label for=\"last_name\">Last name:</label>\n <input type=\"text\"\n id=\"last_name\"\n formControlName=\"last_name\" />\n </div>\n <div class=\"form-field\">\n <label for=\"company\">Company:</label>\n <input type=\"text\"\n id=\"company\"\n formControlName=\"company\" />\n </div>\n <div class=\"form-field\" *ngIf=\"hasValidOptions()\">\n <label for=\"psa\" class=\"select-label\">{{question}}</label>\n <p-dropdown\n formControlName=\"psa\"\n [options]=\"psaOptions\"\n [placeholder]=\"'Select PSA'\"\n styleClass=\"input-select\">\n </p-dropdown>\n </div>\n <div class=\"form-field\">\n <label for=\"enquiry\" class=\"select-label\">How can we help you?</label>\n <div class=\"enquiry-field\">\n <textarea id=\"enquiry\" formControlName=\"enquiry\" class=\"\">\n </textarea>\n <pw-field-error-display [displayError]=\"\n !form.get('enquiry').valid && (form.get('enquiry').touched || submitted)\n \"\n errorMsg=\"Enquiry is required\">\n </pw-field-error-display>\n </div>\n </div>\n </div>\n </div>\n <div class=\"text-end\">\n <div class=\"captcha-wrapper-container\"\n *ngIf=\"isCaptchaVerified\">\n <ngx-recaptcha2 [ngModelOptions]=\"{ standalone: true }\"\n [siteKey]=\"captchaKeyV2\"\n size=\"normal\"\n [(ngModel)]=\"recaptcha\"\n (success)=\"handleSuccess($event)\">\n </ngx-recaptcha2>\n </div>\n <button type=\"submit\"\n (click)=\"onSubmit()\"\n *ngIf=\"!isCaptchaVerified\"\n class=\"sign-btn sign-header-btn mt-3\">\n {{ 'Button.Submit' | transloco }}\n </button>\n </div>\n\n <div class=\"d-flex align-items-center mt-4\">\n <div class=\"icons d-flex align-items-center\">\n <a [eventTracker]=\"{\n category: 'youtube',\n action: 'click',\n label: 'cloudolive-landing-page-b',\n value: 1\n }\"\n [href]=\"youtubeUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <img src=\"/assets/img/icons/youtube.png\"\n class=\"img-fluid youtube-icon\"\n width=\"54\"\n height=\"54\"\n alt=\"\" />\n </a>\n <a [eventTracker]=\"{\n category: 'linkedin',\n action: 'click',\n label: 'cloudolive-landing-page-b',\n value: 1\n }\"\n [href]=\"linkedInUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"ms-3\">\n <img src=\"/assets/img/icons/social/linkedin.svg\"\n class=\"img-fluid linkedin-icon\"\n width=\"48\"\n height=\"48\"\n alt=\"\" />\n </a>\n <i *ngIf=\"canEditResourcesValue\"\n class=\"fa fa-edit in-page-edit-icon text-white cursor-pointer ms-3\"\n (click)=\"openSocialEditModal()\"\n (keydown.enter)=\"openSocialEditModal()\"\n (keydown.space)=\"openSocialEditModal()\"\n title=\"Edit Social Links & Company Name\"></i>\n </div>\n <div class=\"copyright text-white\">\n 2025 {{companyName}}.\n </div>\n </div>\n </form>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n</section>\n\n\n\n<ng-template #bookMeeting\n let-modal>\n <div class=\"modal-header\">\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n </button>\n </div>\n <div class=\"modal-body\">\n <h3 class=\"text-center modal-basic-title\">\n Thanks for getting in touch! Our team will be in contact shortly, or we\n can compare calendars now &amp; schedule a time\n </h3>\n <button type=\"button\"\n [eventTracker]=\"{\n category: 'request-demo',\n action: 'click',\n label: 'cloudolive-landing-page-b',\n value: 1\n }\"\n (click)=\"navigateToBookMeeting()\"\n class=\"sign-btn sign-header-btn mx-auto d-block mb-3\">\n Let's do it\n </button>\n </div>\n</ng-template>\n\n\n<ng-template #editFooterLinksModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit Footer Links</h5>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n\n <div class=\"modal-body\">\n <h4 class=\"mb-3\">Footer Links Section</h4>\n <div cdkDropList (cdkDropListDropped)=\"dropFooterLinks($event)\">\n <div *ngFor=\"let footer of editingFooterLinks.items; let i = index\" class=\"border p-3 mb-3\" cdkDrag>\n <div class=\"row\">\n <div class=\"col-md-5 mb-2\">\n <label for=\"footerTitle{{i}}\" class=\"form-label\">Title</label>\n <input id=\"footerTitle{{i}}\" class=\"form-control\" [(ngModel)]=\"footer.title\" />\n </div>\n <div class=\"col-md-5 mb-2\">\n <label for=\"footerPath{{i}}\" class=\"form-label\">Path</label>\n <input id=\"footerPath{{i}}\" class=\"form-control\" [(ngModel)]=\"footer.path\" />\n </div>\n <div class=\"col-md-2 d-flex justify-content-between align-items-center mt-4\">\n <i class=\"fa fa-trash in-page-trash-icon text-danger cursor-pointer\" (click)=\"removeFooterLink(i)\" (keydown.enter)=\"removeFooterLink(i)\" (keydown.space)=\"removeFooterLink(i)\"></i>\n <i class=\"fa fa-bars in-page-bars-icon cursor-move\" cdkDragHandle></i>\n </div>\n </div>\n\n <!-- Subtitles -->\n <div cdkDropList (cdkDropListDropped)=\"dropSubtitles(i, $event)\">\n <div *ngFor=\"let sub of footer.subtitles; let j = index\" class=\"row border p-3 mb-2 align-items-center\" cdkDrag>\n <div class=\"col-md-5\">\n <label for=\"subtitleTitle{{i}}{{j}}\" class=\"form-label\">Subtitle Title</label>\n <input id=\"subtitleTitle{{i}}{{j}}\" class=\"form-control\" [(ngModel)]=\"sub.title\" />\n </div>\n <div class=\"col-md-5\">\n <label for=\"subtitlePath{{i}}{{j}}\" class=\"form-label\">Subtitle Path</label>\n <input id=\"subtitlePath{{i}}{{j}}\" class=\"form-control\" [(ngModel)]=\"sub.path\" />\n </div>\n <div class=\"col-md-2 d-flex justify-content-between align-items-center mt-4\">\n <i class=\"fa fa-trash in-page-trash-icon text-danger cursor-pointer\" (click)=\"removeSubtitle(i, j)\" (keydown.enter)=\"removeSubtitle(i, j)\" (keydown.space)=\"removeSubtitle(i, j)\"></i>\n <i class=\"fa fa-bars cursor-move in-page-bars-icon\" cdkDragHandle></i>\n </div>\n </div>\n </div>\n\n <button class=\"btn btn-outline-primary btn-sm mt-2\" (click)=\"addSubtitle(i)\">\n + Add Subtitle\n </button>\n </div>\n </div>\n\n <button class=\"btn btn-primary mt-3\" (click)=\"addFooterLink()\">\n + Add Footer Link\n </button>\n </div>\n\n <div class=\"modal-footer\">\n <button class=\"btn btn-secondary\" (click)=\"modal.dismiss()\">Cancel</button>\n <button class=\"btn btn-primary\" (click)=\"saveFooterLinks(modal)\">Save</button>\n </div>\n</ng-template>\n\n\n\n\n\n<ng-template #logoModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Upload Logo</h5>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n <div class=\"modal-body\">\n <pw-custom-uploader\n [aspectRatio]=\"'fullLogo'\"\n [title]=\"'Main Contrast Logo'\"\n [controlName]=\"'logo_main_contrast'\"\n [previewData]=\"previewData\"\n (saveEvent)=\"onSaveFile($event)\">\n </pw-custom-uploader>\n </div>\n</ng-template>\n\n\n\n<ng-template #hubspotEditModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit Hubspot Embed</h5>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n <div class=\"modal-body\">\n <div class=\"mb-3\">\n <label for=\"hubspotId\" class=\"form-label\">Hubspot ID</label>\n <input id=\"hubspotId\" [(ngModel)]=\"editingHubspotId\" class=\"form-control\" />\n </div>\n <div class=\"mb-3\">\n <label for=\"hubspotEmbedDiv\" class=\"form-label\">Embed DIV</label>\n <textarea id=\"hubspotEmbedDiv\" [(ngModel)]=\"editingHubspotHtml\" rows=\"8\" class=\"form-control\"></textarea>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button class=\"btn btn-primary\" (click)=\"saveHubspotHtml(modal)\">Save</button>\n <button class=\"btn btn-secondary\" (click)=\"modal.dismiss()\">Cancel</button>\n </div>\n</ng-template>\n\n\n<ng-template #socialEditModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit Social Links & Company Name</h5>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n <div class=\"modal-body\">\n <div class=\"mb-3\">\n <label for=\"youtubeUrl\" class=\"form-label\">YouTube URL</label>\n <input id=\"youtubeUrl\" [(ngModel)]=\"editingYoutubeUrl\" class=\"form-control\" />\n </div>\n <div class=\"mb-3\">\n <label for=\"linkedinUrl\" class=\"form-label\">LinkedIn URL</label>\n <input id=\"linkedinUrl\" [(ngModel)]=\"editingLinkedInUrl\" class=\"form-control\" />\n </div>\n <div class=\"mb-3\">\n <label for=\"companyName\" class=\"form-label\">Company Name</label>\n <input id=\"companyName\" [(ngModel)]=\"editingCompanyName\" class=\"form-control\" />\n </div>\n </div>\n <div class=\"modal-footer\">\n <button class=\"btn btn-primary\" (click)=\"saveSocialLinks(modal)\">Save</button>\n <button class=\"btn btn-secondary\" (click)=\"modal.dismiss()\">Cancel</button>\n </div>\n</ng-template>\n\n\n\n<ng-template #questionsEditModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit Questions</h5>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n\n <div class=\"modal-body\">\n <h4 class=\"mb-3\">Questions Section</h4>\n <div cdkDropList (cdkDropListDropped)=\"dropQuestions($event)\">\n <div *ngFor=\"let q of editingQuestions; let i = index\" class=\"border p-3 mb-3\" cdkDrag>\n <div class=\"row\">\n <div class=\"col-md-11 mb-2\">\n <label for=\"questionText{{i}}\" class=\"form-label\">Question</label>\n <input id=\"questionText{{i}}\" class=\"form-control\" [(ngModel)]=\"q.question\" placeholder=\"Enter question\" />\n </div>\n <div class=\"col-md-1 d-flex justify-content-end align-items-start mt-4\">\n <i class=\"fa fa-bars in-page-bars-icon cursor-move\" cdkDragHandle></i>\n </div>\n </div>\n\n <!-- Options Section -->\n <div cdkDropList (cdkDropListDropped)=\"dropQuestionOptions(i, $event)\">\n <div *ngFor=\"let opt of q.options; let j = index\" class=\"row border p-3 mb-2 align-items-center\" cdkDrag>\n <div class=\"col-md-7 mb-2\">\n <label for=\"questionOption{{i}}{{j}}\" class=\"form-label\">Option</label>\n <input id=\"questionOption{{i}}{{j}}\" class=\"form-control\" [(ngModel)]=\"opt.option\" placeholder=\"Enter option\" />\n </div>\n <div class=\"col-md-2 d-flex justify-content-between align-items-center mt-4\">\n <i class=\"fa fa-trash in-page-trash-icon text-danger cursor-pointer\" (click)=\"removeQuestionOption(i, j)\" (keydown.enter)=\"removeQuestionOption(i, j)\" (keydown.enter)=\"removeQuestionOption(i, j)\"></i>\n <i class=\"fa fa-bars in-page-bars-icon cursor-move\" cdkDragHandle></i>\n </div>\n </div>\n </div>\n\n <button class=\"btn btn-outline-primary btn-sm mt-2\" (click)=\"addQuestionOption(i)\">+ Add Option</button>\n </div>\n </div>\n\n <button class=\"btn btn-primary mt-3\" (click)=\"addNewQuestion()\">+ Add Question</button>\n </div>\n\n <div class=\"modal-footer\">\n <button class=\"btn btn-secondary\" (click)=\"modal.dismiss()\">Cancel</button>\n <button class=\"btn btn-primary\" (click)=\"saveQuestions(modal)\">Save</button>\n </div>\n</ng-template>\n\n\n\n", styles: [".product-explainer-section{background-color:#000}.footer-section input.form-control,.footer-section select.form-control,.footer-section textarea.form-control{background-color:#fff;border:none;color:#000;font-size:14px}.btn-primary{background-color:#007bff;border:none}.site-column{margin-top:2.9rem}.email-section{color:#fff;font-size:2rem}.address-section{margin-top:5rem}.address-text{line-height:2.2rem}.user-info{font-size:1.5rem}.user-info-label{font-size:1.7rem;font-weight:700}.contact-form form .form-field{display:flex;align-items:center;margin-bottom:1.2rem}.contact-form form .form-field label{width:130px;min-width:130px;margin:0;font-size:14px;color:#fff;font-weight:600;text-transform:uppercase;letter-spacing:1px}.contact-form form .form-field p-dropdown{width:100%}.contact-form form .form-field input,.contact-form form .form-field select,.contact-form form .form-field textarea,.contact-form form .form-field ::ng-deep p-dropdown .p-inputwrapper{flex:1;border:none;border-radius:30px;padding:12px 20px;font-size:14px;width:100%!important;max-width:100%;color:#000}.contact-form form .form-field textarea{resize:vertical}.contact-form form .submit-button{background-color:#3b82f6;border:none;border-radius:30px;font-size:16px;font-weight:500;padding:10px 24px;margin-top:1.2rem}.input-select{height:43px}.select-label{width:210px!important}.copyright{margin-top:2rem;margin-left:4rem;font-size:19px;font-weight:700}.d-flex img{margin-right:0!important}.youtube-icon{height:38px}.enquiry-field{margin-left:.5rem;width:63%}::ng-deep .text-danger{margin-top:.25rem!important;margin-left:.5rem!important}@media (min-width: 768px){.hubspot-container{margin-top:-3rem}}@media (min-width: 768px) and (max-width: 1200px){.container{padding:0rem 6rem!important}}.link-label{cursor:pointer;transition:color .3s}.link-label:hover{color:var(--first)}.icons img{transition:transform .3s ease,filter .3s ease;cursor:pointer}.icons img:hover{transform:scale(1.1);filter:brightness(1.2)}.logo-image{max-width:160px;width:160px;height:35px;object-fit:contain;aspect-ratio:160/35}\n"], dependencies: [{ kind: "directive", type: i3$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i9.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i9.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i9.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i2$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "directive", type: i8.EventTrackerDirective, selector: "[eventTracker]", inputs: ["eventTracker"] }, { kind: "directive", type: i8.LazyImgDirective, selector: "img" }, { kind: "component", type: i11.ReCaptcha2Component, selector: "ngx-recaptcha2", inputs: ["theme", "size"] }, { kind: "component", type: i12.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i6.CustomUploaderComponent, selector: "pw-custom-uploader", inputs: ["controlName", "previewData", "aspectRatio", "title"], outputs: ["saveEvent"] }, { kind: "component", type: i6.FieldErrorDisplayComponent, selector: "pw-field-error-display", inputs: ["errorMsg", "displayError"] }, { kind: "pipe", type: i10.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
639
+ }
640
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: Trial4ContactUsComponent, decorators: [{
641
+ type: Component,
642
+ args: [{ selector: 'pw-trial-4-contact-us', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section #footerSection class=\"bg-black text-white py-5 footer-section\">\n <div class=\"container\" *ngIf=\"isFooterVisible\">\n <div class=\"row\">\n\n <!-- LEFT COLUMN -->\n <div class=\"col-md-6 mb-4 d-flex flex-column justify-content-between\" [ngClass]=\"{ 'site-column': getFooterHubspotForm() }\">\n <div>\n <h3 class=\"mb-4 d-flex align-items-center\">\n <span class=\"me-2 text-white\">Site Map:</span>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon cursor-pointer text-white ms-3\" (click)=\"openEditFooterLinksModal(editFooterLinksModal)\" (keydown.enter)=\"openEditFooterLinksModal(editFooterLinksModal)\" (keydown.space)=\"openEditFooterLinksModal(editFooterLinksModal)\" ngbTooltip=\"Edit Footer Links\"></i>\n </h3>\n <ul class=\"mt-4\">\n <li routerLink=\"/\"\n class=\"cursor-pointer user-info-label link-label\"> Home </li>\n <li *ngFor=\"let link of footerLinks\" [routerLink]=\"link?.path\"\n class=\"cursor-pointer user-info-label link-label mt-4\"><span *ngIf=\"link?.title\">{{link?.title}}</span> </li>\n <li routerLink=\"/login\"\n class=\"cursor-pointer user-info-label mt-4 link-label\"> Log in </li>\n <li [routerLink]=\"'/privacy-and-tos/' + tosId\"\n class=\"cursor-pointer user-info-label mt-4 link-label\"> Privacy statement </li>\n </ul>\n <p class=\"address-section email-section mb-4\">\n <span class=\"user-info-label\">Email: </span>\n <ng-container *ngIf=\"!isEditingEmail; else editEmail\">\n <span class=\"user-info\">{{ email }}</span>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon text-white cursor-pointer ms-3\" (click)=\"isEditingEmail = true\" (keydown.enter)=\"isEditingEmail = true\" (keydown.space)=\"isEditingEmail = true\"></i>\n </ng-container>\n\n <ng-template #editEmail>\n <input\n class=\"form-control d-inline w-auto\"\n [(ngModel)]=\"editingEmail\"\n />\n <button class=\"btn btn-sm btn-primary ms-2\" (click)=\"saveEmail()\">Save</button>\n <button class=\"btn btn-sm btn-secondary ms-2\" (click)=\"isEditingEmail = false\">Cancel</button>\n </ng-template>\n </p>\n <span class=\"email-section mt-3 address-text\">\n <span class=\"user-info-label\">\n Address:\n <i *ngIf=\"canEditResourcesValue\"\n class=\"fa fa-edit in-page-edit-icon cursor-pointer ms-2 text-white\"\n title=\"Edit Address\"\n (click)=\"isEditingStreet = true\"\n (keydown.enter)=\"isEditingStreet = true\"\n (keydown.space)=\"isEditingStreet = true\"></i>\n </span><br/>\n\n <ng-container *ngIf=\"!isEditingStreet; else editStreetBlock\">\n <span class=\"address-text user-info\">{{ street }}</span>\n </ng-container>\n\n <ng-template #editStreetBlock>\n <div class=\"d-flex align-items-center mt-3\">\n <input class=\"form-control form-control-sm\" [(ngModel)]=\"editingStreet\" />\n <button class=\"btn btn-sm btn-primary ms-2\" (click)=\"saveStreet()\">Save</button>\n <button class=\"btn btn-sm btn-secondary ms-2\" (click)=\"cancelStreet()\">Cancel</button>\n </div>\n </ng-template>\n\n </span>\n\n </div>\n <div class=\"d-flex\">\n <img [src]=\"logo\"\n alt=\"Company logo\"\n class=\"img-fluid mt-4 logo-image cursor-pointer\"\n width=\"160\"\n height=\"35\"\n (click)=\"scrollToTop()\"\n (keydown.enter)=\"scrollToTop()\"\n (keydown.space)=\"scrollToTop()\"\n title=\"Click to go to top of page\" />\n <i *ngIf=\"canEditResourcesValue\"\n class=\"fa fa-edit in-page-edit-icon fa-sm ms-3 cursor-pointer text-white align-self-center mt-3\"\n (click)=\"openLogoEditModal()\"\n (keydown.enter)=\"openLogoEditModal()\"\n (keydown.space)=\"openLogoEditModal()\"\n title=\"Edit Logo\"></i>\n </div>\n </div>\n\n <!-- RIGHT COLUMN -->\n <div class=\"col-md-6\" *ngIf=\"isFooterVisible\">\n <ng-container *ngIf=\"getFooterHubspotForm() as footerItem; else defaultForm\">\n <div class=\"d-flex\">\n <div\n *ngIf=\"isHubspotReady\"\n class=\"hubspot-container w-100 content-loaded\"\n [innerHTML]=\"hubspotHtml\"\n (load)=\"onHubspotLoad($event)\">\n </div>\n <i *ngIf=\"canEditResourcesValue\"\n class=\"fa fa-edit in-page-edit-icon text-white cursor-pointer\"\n (click)=\"openHubspotEditModal(footerItem)\"\n (keydown.enter)=\"openHubspotEditModal(footerItem)\"\n (keydown.space)=\"openHubspotEditModal(footerItem)\"\n title=\"Edit Hubspot Embed\"></i>\n </div>\n </ng-container>\n\n <ng-template #defaultForm>\n <div class=\"d-flex\">\n <h3 class=\"text-white mb-4\"> <span class=\"text-white\">Get in touch:</span></h3>\n <i *ngIf=\"canEditResourcesValue\"\n class=\"fa fa-edit in-page-edit-icon text-white cursor-pointer ms-3 mt-2\"\n (click)=\"openQuestionsEditModal()\"\n (keydown.enter)=\"openQuestionsEditModal()\"\n (keydown.space)=\"openQuestionsEditModal()\"\n title=\"Edit Questions\"></i>\n </div>\n <div class=\"contact-form\">\n <form [formGroup]=\"form\">\n <div class=\"mb-3\">\n <div class=\"email\">\n <div class=\"form-field\">\n <label for=\"email\">Email:</label>\n <div class=\"w-100\">\n <input type=\"text\"\n class=\"mb-1\"\n id=\"email\"\n formControlName=\"email\" />\n <pw-field-error-display [displayError]=\"\n !form.get('email').valid && (form.get('email').touched || submitted)\n \"\n errorMsg=\"Email is required\">\n </pw-field-error-display>\n </div>\n </div>\n <div class=\"form-field\">\n <label for=\"first_name\">First name:</label>\n <div class=\"w-100\">\n <input input type=\"text\"\n id=\"first_name\"\n formControlName=\"first_name\" />\n <pw-field-error-display [displayError]=\"\n !form.get('first_name').valid && (form.get('first_name').touched || submitted)\n \"\n errorMsg=\"First name is required\">\n </pw-field-error-display>\n </div>\n </div>\n <div class=\"form-field\">\n <label for=\"last_name\">Last name:</label>\n <input type=\"text\"\n id=\"last_name\"\n formControlName=\"last_name\" />\n </div>\n <div class=\"form-field\">\n <label for=\"company\">Company:</label>\n <input type=\"text\"\n id=\"company\"\n formControlName=\"company\" />\n </div>\n <div class=\"form-field\" *ngIf=\"hasValidOptions()\">\n <label for=\"psa\" class=\"select-label\">{{question}}</label>\n <p-dropdown\n formControlName=\"psa\"\n [options]=\"psaOptions\"\n [placeholder]=\"'Select PSA'\"\n styleClass=\"input-select\">\n </p-dropdown>\n </div>\n <div class=\"form-field\">\n <label for=\"enquiry\" class=\"select-label\">How can we help you?</label>\n <div class=\"enquiry-field\">\n <textarea id=\"enquiry\" formControlName=\"enquiry\" class=\"\">\n </textarea>\n <pw-field-error-display [displayError]=\"\n !form.get('enquiry').valid && (form.get('enquiry').touched || submitted)\n \"\n errorMsg=\"Enquiry is required\">\n </pw-field-error-display>\n </div>\n </div>\n </div>\n </div>\n <div class=\"text-end\">\n <div class=\"captcha-wrapper-container\"\n *ngIf=\"isCaptchaVerified\">\n <ngx-recaptcha2 [ngModelOptions]=\"{ standalone: true }\"\n [siteKey]=\"captchaKeyV2\"\n size=\"normal\"\n [(ngModel)]=\"recaptcha\"\n (success)=\"handleSuccess($event)\">\n </ngx-recaptcha2>\n </div>\n <button type=\"submit\"\n (click)=\"onSubmit()\"\n *ngIf=\"!isCaptchaVerified\"\n class=\"sign-btn sign-header-btn mt-3\">\n {{ 'Button.Submit' | transloco }}\n </button>\n </div>\n\n <div class=\"d-flex align-items-center mt-4\">\n <div class=\"icons d-flex align-items-center\">\n <a [eventTracker]=\"{\n category: 'youtube',\n action: 'click',\n label: 'cloudolive-landing-page-b',\n value: 1\n }\"\n [href]=\"youtubeUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <img src=\"/assets/img/icons/youtube.png\"\n class=\"img-fluid youtube-icon\"\n width=\"54\"\n height=\"54\"\n alt=\"\" />\n </a>\n <a [eventTracker]=\"{\n category: 'linkedin',\n action: 'click',\n label: 'cloudolive-landing-page-b',\n value: 1\n }\"\n [href]=\"linkedInUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"ms-3\">\n <img src=\"/assets/img/icons/social/linkedin.svg\"\n class=\"img-fluid linkedin-icon\"\n width=\"48\"\n height=\"48\"\n alt=\"\" />\n </a>\n <i *ngIf=\"canEditResourcesValue\"\n class=\"fa fa-edit in-page-edit-icon text-white cursor-pointer ms-3\"\n (click)=\"openSocialEditModal()\"\n (keydown.enter)=\"openSocialEditModal()\"\n (keydown.space)=\"openSocialEditModal()\"\n title=\"Edit Social Links & Company Name\"></i>\n </div>\n <div class=\"copyright text-white\">\n 2025 {{companyName}}.\n </div>\n </div>\n </form>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n</section>\n\n\n\n<ng-template #bookMeeting\n let-modal>\n <div class=\"modal-header\">\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n </button>\n </div>\n <div class=\"modal-body\">\n <h3 class=\"text-center modal-basic-title\">\n Thanks for getting in touch! Our team will be in contact shortly, or we\n can compare calendars now &amp; schedule a time\n </h3>\n <button type=\"button\"\n [eventTracker]=\"{\n category: 'request-demo',\n action: 'click',\n label: 'cloudolive-landing-page-b',\n value: 1\n }\"\n (click)=\"navigateToBookMeeting()\"\n class=\"sign-btn sign-header-btn mx-auto d-block mb-3\">\n Let's do it\n </button>\n </div>\n</ng-template>\n\n\n<ng-template #editFooterLinksModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit Footer Links</h5>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n\n <div class=\"modal-body\">\n <h4 class=\"mb-3\">Footer Links Section</h4>\n <div cdkDropList (cdkDropListDropped)=\"dropFooterLinks($event)\">\n <div *ngFor=\"let footer of editingFooterLinks.items; let i = index\" class=\"border p-3 mb-3\" cdkDrag>\n <div class=\"row\">\n <div class=\"col-md-5 mb-2\">\n <label for=\"footerTitle{{i}}\" class=\"form-label\">Title</label>\n <input id=\"footerTitle{{i}}\" class=\"form-control\" [(ngModel)]=\"footer.title\" />\n </div>\n <div class=\"col-md-5 mb-2\">\n <label for=\"footerPath{{i}}\" class=\"form-label\">Path</label>\n <input id=\"footerPath{{i}}\" class=\"form-control\" [(ngModel)]=\"footer.path\" />\n </div>\n <div class=\"col-md-2 d-flex justify-content-between align-items-center mt-4\">\n <i class=\"fa fa-trash in-page-trash-icon text-danger cursor-pointer\" (click)=\"removeFooterLink(i)\" (keydown.enter)=\"removeFooterLink(i)\" (keydown.space)=\"removeFooterLink(i)\"></i>\n <i class=\"fa fa-bars in-page-bars-icon cursor-move\" cdkDragHandle></i>\n </div>\n </div>\n\n <!-- Subtitles -->\n <div cdkDropList (cdkDropListDropped)=\"dropSubtitles(i, $event)\">\n <div *ngFor=\"let sub of footer.subtitles; let j = index\" class=\"row border p-3 mb-2 align-items-center\" cdkDrag>\n <div class=\"col-md-5\">\n <label for=\"subtitleTitle{{i}}{{j}}\" class=\"form-label\">Subtitle Title</label>\n <input id=\"subtitleTitle{{i}}{{j}}\" class=\"form-control\" [(ngModel)]=\"sub.title\" />\n </div>\n <div class=\"col-md-5\">\n <label for=\"subtitlePath{{i}}{{j}}\" class=\"form-label\">Subtitle Path</label>\n <input id=\"subtitlePath{{i}}{{j}}\" class=\"form-control\" [(ngModel)]=\"sub.path\" />\n </div>\n <div class=\"col-md-2 d-flex justify-content-between align-items-center mt-4\">\n <i class=\"fa fa-trash in-page-trash-icon text-danger cursor-pointer\" (click)=\"removeSubtitle(i, j)\" (keydown.enter)=\"removeSubtitle(i, j)\" (keydown.space)=\"removeSubtitle(i, j)\"></i>\n <i class=\"fa fa-bars cursor-move in-page-bars-icon\" cdkDragHandle></i>\n </div>\n </div>\n </div>\n\n <button class=\"btn btn-outline-primary btn-sm mt-2\" (click)=\"addSubtitle(i)\">\n + Add Subtitle\n </button>\n </div>\n </div>\n\n <button class=\"btn btn-primary mt-3\" (click)=\"addFooterLink()\">\n + Add Footer Link\n </button>\n </div>\n\n <div class=\"modal-footer\">\n <button class=\"btn btn-secondary\" (click)=\"modal.dismiss()\">Cancel</button>\n <button class=\"btn btn-primary\" (click)=\"saveFooterLinks(modal)\">Save</button>\n </div>\n</ng-template>\n\n\n\n\n\n<ng-template #logoModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Upload Logo</h5>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n <div class=\"modal-body\">\n <pw-custom-uploader\n [aspectRatio]=\"'fullLogo'\"\n [title]=\"'Main Contrast Logo'\"\n [controlName]=\"'logo_main_contrast'\"\n [previewData]=\"previewData\"\n (saveEvent)=\"onSaveFile($event)\">\n </pw-custom-uploader>\n </div>\n</ng-template>\n\n\n\n<ng-template #hubspotEditModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit Hubspot Embed</h5>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n <div class=\"modal-body\">\n <div class=\"mb-3\">\n <label for=\"hubspotId\" class=\"form-label\">Hubspot ID</label>\n <input id=\"hubspotId\" [(ngModel)]=\"editingHubspotId\" class=\"form-control\" />\n </div>\n <div class=\"mb-3\">\n <label for=\"hubspotEmbedDiv\" class=\"form-label\">Embed DIV</label>\n <textarea id=\"hubspotEmbedDiv\" [(ngModel)]=\"editingHubspotHtml\" rows=\"8\" class=\"form-control\"></textarea>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button class=\"btn btn-primary\" (click)=\"saveHubspotHtml(modal)\">Save</button>\n <button class=\"btn btn-secondary\" (click)=\"modal.dismiss()\">Cancel</button>\n </div>\n</ng-template>\n\n\n<ng-template #socialEditModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit Social Links & Company Name</h5>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n <div class=\"modal-body\">\n <div class=\"mb-3\">\n <label for=\"youtubeUrl\" class=\"form-label\">YouTube URL</label>\n <input id=\"youtubeUrl\" [(ngModel)]=\"editingYoutubeUrl\" class=\"form-control\" />\n </div>\n <div class=\"mb-3\">\n <label for=\"linkedinUrl\" class=\"form-label\">LinkedIn URL</label>\n <input id=\"linkedinUrl\" [(ngModel)]=\"editingLinkedInUrl\" class=\"form-control\" />\n </div>\n <div class=\"mb-3\">\n <label for=\"companyName\" class=\"form-label\">Company Name</label>\n <input id=\"companyName\" [(ngModel)]=\"editingCompanyName\" class=\"form-control\" />\n </div>\n </div>\n <div class=\"modal-footer\">\n <button class=\"btn btn-primary\" (click)=\"saveSocialLinks(modal)\">Save</button>\n <button class=\"btn btn-secondary\" (click)=\"modal.dismiss()\">Cancel</button>\n </div>\n</ng-template>\n\n\n\n<ng-template #questionsEditModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit Questions</h5>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n\n <div class=\"modal-body\">\n <h4 class=\"mb-3\">Questions Section</h4>\n <div cdkDropList (cdkDropListDropped)=\"dropQuestions($event)\">\n <div *ngFor=\"let q of editingQuestions; let i = index\" class=\"border p-3 mb-3\" cdkDrag>\n <div class=\"row\">\n <div class=\"col-md-11 mb-2\">\n <label for=\"questionText{{i}}\" class=\"form-label\">Question</label>\n <input id=\"questionText{{i}}\" class=\"form-control\" [(ngModel)]=\"q.question\" placeholder=\"Enter question\" />\n </div>\n <div class=\"col-md-1 d-flex justify-content-end align-items-start mt-4\">\n <i class=\"fa fa-bars in-page-bars-icon cursor-move\" cdkDragHandle></i>\n </div>\n </div>\n\n <!-- Options Section -->\n <div cdkDropList (cdkDropListDropped)=\"dropQuestionOptions(i, $event)\">\n <div *ngFor=\"let opt of q.options; let j = index\" class=\"row border p-3 mb-2 align-items-center\" cdkDrag>\n <div class=\"col-md-7 mb-2\">\n <label for=\"questionOption{{i}}{{j}}\" class=\"form-label\">Option</label>\n <input id=\"questionOption{{i}}{{j}}\" class=\"form-control\" [(ngModel)]=\"opt.option\" placeholder=\"Enter option\" />\n </div>\n <div class=\"col-md-2 d-flex justify-content-between align-items-center mt-4\">\n <i class=\"fa fa-trash in-page-trash-icon text-danger cursor-pointer\" (click)=\"removeQuestionOption(i, j)\" (keydown.enter)=\"removeQuestionOption(i, j)\" (keydown.enter)=\"removeQuestionOption(i, j)\"></i>\n <i class=\"fa fa-bars in-page-bars-icon cursor-move\" cdkDragHandle></i>\n </div>\n </div>\n </div>\n\n <button class=\"btn btn-outline-primary btn-sm mt-2\" (click)=\"addQuestionOption(i)\">+ Add Option</button>\n </div>\n </div>\n\n <button class=\"btn btn-primary mt-3\" (click)=\"addNewQuestion()\">+ Add Question</button>\n </div>\n\n <div class=\"modal-footer\">\n <button class=\"btn btn-secondary\" (click)=\"modal.dismiss()\">Cancel</button>\n <button class=\"btn btn-primary\" (click)=\"saveQuestions(modal)\">Save</button>\n </div>\n</ng-template>\n\n\n\n", styles: [".product-explainer-section{background-color:#000}.footer-section input.form-control,.footer-section select.form-control,.footer-section textarea.form-control{background-color:#fff;border:none;color:#000;font-size:14px}.btn-primary{background-color:#007bff;border:none}.site-column{margin-top:2.9rem}.email-section{color:#fff;font-size:2rem}.address-section{margin-top:5rem}.address-text{line-height:2.2rem}.user-info{font-size:1.5rem}.user-info-label{font-size:1.7rem;font-weight:700}.contact-form form .form-field{display:flex;align-items:center;margin-bottom:1.2rem}.contact-form form .form-field label{width:130px;min-width:130px;margin:0;font-size:14px;color:#fff;font-weight:600;text-transform:uppercase;letter-spacing:1px}.contact-form form .form-field p-dropdown{width:100%}.contact-form form .form-field input,.contact-form form .form-field select,.contact-form form .form-field textarea,.contact-form form .form-field ::ng-deep p-dropdown .p-inputwrapper{flex:1;border:none;border-radius:30px;padding:12px 20px;font-size:14px;width:100%!important;max-width:100%;color:#000}.contact-form form .form-field textarea{resize:vertical}.contact-form form .submit-button{background-color:#3b82f6;border:none;border-radius:30px;font-size:16px;font-weight:500;padding:10px 24px;margin-top:1.2rem}.input-select{height:43px}.select-label{width:210px!important}.copyright{margin-top:2rem;margin-left:4rem;font-size:19px;font-weight:700}.d-flex img{margin-right:0!important}.youtube-icon{height:38px}.enquiry-field{margin-left:.5rem;width:63%}::ng-deep .text-danger{margin-top:.25rem!important;margin-left:.5rem!important}@media (min-width: 768px){.hubspot-container{margin-top:-3rem}}@media (min-width: 768px) and (max-width: 1200px){.container{padding:0rem 6rem!important}}.link-label{cursor:pointer;transition:color .3s}.link-label:hover{color:var(--first)}.icons img{transition:transform .3s ease,filter .3s ease;cursor:pointer}.icons img:hover{transform:scale(1.1);filter:brightness(1.2)}.logo-image{max-width:160px;width:160px;height:35px;object-fit:contain;aspect-ratio:160/35}\n"] }]
643
+ }], ctorParameters: () => [{ type: i1$1.UntypedFormBuilder }, { type: i2.AuthService }, { type: i3.CrmService }, { type: i3$1.DomSanitizer }, { type: i5.AdminService }, { type: i0.Injector }, { type: i2.AbTestService }, { type: i2$1.NgbModal }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
644
+ type: Inject,
645
+ args: [DOCUMENT]
646
+ }] }], propDecorators: { footerSection: [{
647
+ type: ViewChild,
648
+ args: ['footerSection', { static: true }]
649
+ }], content: [{
650
+ type: ViewChild,
651
+ args: ['bookMeeting', { static: true }]
652
+ }], editFooterLinksModal: [{
653
+ type: ViewChild,
654
+ args: ['editFooterLinksModal']
655
+ }], logoModal: [{
656
+ type: ViewChild,
657
+ args: ['logoModal']
658
+ }], logoUploader: [{
659
+ type: ViewChild,
660
+ args: ['logoUploader']
661
+ }], hubspotEditModal: [{
662
+ type: ViewChild,
663
+ args: ['hubspotEditModal']
664
+ }], socialEditModal: [{
665
+ type: ViewChild,
666
+ args: ['socialEditModal']
667
+ }], questionsEditModal: [{
668
+ type: ViewChild,
669
+ args: ['questionsEditModal']
670
+ }], subscriptionId: [{
671
+ type: Input
672
+ }], sourceId: [{
673
+ type: Input
674
+ }], masterSubscriptionId: [{
675
+ type: Input
676
+ }], experimentName: [{
677
+ type: Input
678
+ }], microserviceName: [{
679
+ type: Input
680
+ }], shardName: [{
681
+ type: Input
682
+ }], user: [{
683
+ type: Input
684
+ }], userLoggedIn: [{
685
+ type: Input
686
+ }] } });
687
+
688
+ /**
689
+ * Standalone module for Trial4ContactUsComponent (pw-trial-4-contact-us)
690
+ * Lightweight alternative to importing entire ResourceSharedModule
691
+ */
692
+ class Trial4ContactUsModule {
693
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: Trial4ContactUsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
694
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.11", ngImport: i0, type: Trial4ContactUsModule, declarations: [Trial4ContactUsComponent], imports: [CommonModule,
695
+ FormsModule,
696
+ ReactiveFormsModule,
697
+ RouterModule,
698
+ DragDropModule,
699
+ NgbModalModule,
700
+ NgbTooltipModule,
701
+ DirectivesModule,
702
+ PipesModule,
703
+ CoreTranslocoModule,
704
+ NgxCaptchaModule,
705
+ DropdownModule,
706
+ ProfileImageCropperModule, // For pw-custom-uploader + pw-image-cropper
707
+ FieldErrorDisplayModule, // For pw-field-error-display
708
+ AdminModuleUtilsModule], exports: [Trial4ContactUsComponent] }); }
709
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: Trial4ContactUsModule, imports: [CommonModule,
710
+ FormsModule,
711
+ ReactiveFormsModule,
712
+ RouterModule,
713
+ DragDropModule,
714
+ NgbModalModule,
715
+ NgbTooltipModule,
716
+ DirectivesModule,
717
+ PipesModule,
718
+ CoreTranslocoModule,
719
+ NgxCaptchaModule,
720
+ DropdownModule,
721
+ ProfileImageCropperModule, // For pw-custom-uploader + pw-image-cropper
722
+ FieldErrorDisplayModule, // For pw-field-error-display
723
+ AdminModuleUtilsModule] }); }
724
+ }
725
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: Trial4ContactUsModule, decorators: [{
726
+ type: NgModule,
727
+ args: [{
728
+ declarations: [Trial4ContactUsComponent],
729
+ imports: [
730
+ CommonModule,
731
+ FormsModule,
732
+ ReactiveFormsModule,
733
+ RouterModule,
734
+ DragDropModule,
735
+ NgbModalModule,
736
+ NgbTooltipModule,
737
+ DirectivesModule,
738
+ PipesModule,
739
+ CoreTranslocoModule,
740
+ NgxCaptchaModule,
741
+ DropdownModule,
742
+ ProfileImageCropperModule, // For pw-custom-uploader + pw-image-cropper
743
+ FieldErrorDisplayModule, // For pw-field-error-display
744
+ AdminModuleUtilsModule
745
+ ],
746
+ exports: [Trial4ContactUsComponent]
747
+ }]
748
+ }] });
749
+
750
+ /**
751
+ * Lazy-loading wrapper for ResourceEditCard
752
+ */
753
+ class ResourceEditCardLazyComponent {
754
+ constructor() {
755
+ this.canEdit = false;
756
+ this.updated = new EventEmitter();
757
+ this.componentRef = null;
758
+ this.loading = false;
759
+ }
760
+ async ngOnChanges(changes) {
761
+ if (this.canEdit && !this.componentRef && !this.loading) {
762
+ await this.loadEditCard();
763
+ }
764
+ else if (!this.canEdit && this.componentRef) {
765
+ this.container.clear();
766
+ this.componentRef = null;
767
+ }
768
+ else if (this.componentRef && (changes['id'] || changes['resourceData'])) {
769
+ // Update existing component inputs
770
+ this.componentRef.instance.id = this.id;
771
+ this.componentRef.instance.resourceData = this.resourceData;
772
+ }
773
+ }
774
+ async loadEditCard() {
775
+ if (this.componentRef || this.loading)
776
+ return; // Prevent double loading
777
+ this.loading = true; // Set BEFORE async operation
778
+ try {
779
+ // Dynamically import ResourceEditCard component (145 KB)
780
+ const module = await Promise.resolve().then(function () { return resourceEditCard_component; });
781
+ const ResourceEditCardComponent = module.ResourceEditCardComponent;
782
+ // Ensure container exists and is clear
783
+ if (!this.container)
784
+ return;
785
+ this.container.clear();
786
+ // Create component dynamically (only once)
787
+ this.componentRef = this.container.createComponent(ResourceEditCardComponent);
788
+ this.componentRef.instance.id = this.id;
789
+ this.componentRef.instance.resourceData = this.resourceData;
790
+ this.componentRef.instance.updated.subscribe(() => this.updated.emit());
791
+ this.loading = false;
792
+ }
793
+ catch (error) {
794
+ console.error('Failed to load ResourceEditCard:', error);
795
+ this.loading = false;
796
+ }
797
+ }
798
+ ngOnDestroy() {
799
+ this.componentRef?.destroy();
800
+ }
801
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceEditCardLazyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
802
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: ResourceEditCardLazyComponent, selector: "pw-resource-edit-card-lazy", inputs: { id: "id", resourceData: "resourceData", canEdit: "canEdit" }, outputs: { updated: "updated" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["editCardContainer"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `<ng-container #editCardContainer></ng-container>`, isInline: true }); }
803
+ }
804
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceEditCardLazyComponent, decorators: [{
805
+ type: Component,
806
+ args: [{
807
+ selector: 'pw-resource-edit-card-lazy',
808
+ template: `<ng-container #editCardContainer></ng-container>`
809
+ }]
810
+ }], propDecorators: { container: [{
811
+ type: ViewChild,
812
+ args: ['editCardContainer', { read: ViewContainerRef, static: true }]
813
+ }], id: [{
814
+ type: Input
815
+ }], resourceData: [{
816
+ type: Input
817
+ }], canEdit: [{
818
+ type: Input
819
+ }], updated: [{
820
+ type: Output
821
+ }] } });
822
+
823
+ class ResourceCompanyCardComponent extends AppBaseComponent {
824
+ constructor(injector) {
825
+ super(injector);
826
+ this.getPosts = new EventEmitter();
827
+ this.destroy$ = new Subject();
828
+ this.canEditResourcesValue = false;
829
+ this.header = '';
830
+ this.data = [];
831
+ this.vendor = false;
832
+ this.postData = false;
833
+ this.filteredData = [];
834
+ this.first = 0;
835
+ this.rows = 12;
836
+ }
837
+ ngOnChanges() {
838
+ this.search();
839
+ }
840
+ ngOnInit() {
841
+ if (this.userLoggedIn) {
842
+ this.updateCanEditResourcesValue();
843
+ this.localStorage.getItem$('product').subscribe(res => {
844
+ const data = res ? JSON.parse(res) : null;
845
+ this.subscriptionId = data?.subscriptionId;
846
+ });
847
+ }
848
+ }
849
+ search(keywords) {
850
+ if (keywords) {
851
+ this.filteredData = this.data.filter(x => x.title.toLowerCase().includes(keywords.toLowerCase()));
852
+ if (this.filteredData.length === 0) {
853
+ this.postData = true;
854
+ }
855
+ else {
856
+ this.postData = false;
857
+ }
858
+ }
859
+ else {
860
+ this.filteredData = [...this.data];
861
+ this.postData = false;
862
+ }
863
+ }
864
+ onPageChange(event) {
865
+ this.first = event.first;
866
+ this.rows = event.rows;
867
+ }
868
+ ngOnDestroy() {
869
+ this.destroy$.next();
870
+ this.destroy$.complete();
871
+ }
872
+ updateCanEditResourcesValue() {
873
+ this.canEditResourcesValue = HelperService.canEditResources(this.user, this.userLoggedIn, this.permissionService);
874
+ }
875
+ canEditResources() {
876
+ return this.canEditResourcesValue;
877
+ }
878
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceCompanyCardComponent, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); }
879
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: ResourceCompanyCardComponent, selector: "pw-resource-company-card", inputs: { header: "header", data: "data", integrationCountDisplay: "integrationCountDisplay", vendor: "vendor", user: "user", userLoggedIn: "userLoggedIn" }, outputs: { getPosts: "getPosts" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div [ngClass]=\"{ 'vendors-distributor-wrapper': !vendor }\">\n <div class=\"d-flex justify-content-between align-items-center mb-3 search-container\">\n <div>\n <span class=\"int-span\">{{header}}</span>\n </div>\n <div class=\"search-wrapper position-relative\" *ngIf=\"integrationCountDisplay > 0\">\n <i class=\"fa fa-search search-icon\"></i>\n <input type=\"text\"\n\n (keyup)=\"search($event.target.value)\"\n placeholder=\"Search eg security\"\n class=\"search-input top-search-input\" />\n </div>\n\n </div>\n\n <div *ngIf=\"postData\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n\n <div class=\"row\" *ngIf=\"!postData && integrationCountDisplay > 0\">\n <div class=\"col-md-3 mt-4\"\n *ngFor=\"let img of filteredData | slice:first:(first + rows)\">\n <div class=\"boxes d-flex align-items-center justify-content-center\">\n <ng-container *ngIf=\"img?.companyImg; else checkRectangular\">\n <img [src]=\"img.companyImg\" alt=\"Vendor Company Icon\" class=\"vendor-icon\" />\n </ng-container>\n\n <ng-template #checkRectangular>\n <ng-container *ngIf=\"img?.rectangular_picture?.url; else noImage\">\n <ng-container *ngIf=\"!img.rectangular_picture.url.includes('default-photo'); else showPostName\">\n <ng-container *ngIf=\"img?.showcase; else noLinkImage\">\n <a class=\"vendor-link\" [href]=\"img.external_url || ('/resources/view/' + img.slug)\">\n <img [src]=\"img.rectangular_picture.url\" alt=\"Vendor Rectangular Company Icon\" class=\"vendor-icon\" />\n </a>\n </ng-container>\n <ng-template #noLinkImage>\n <img [src]=\"img.rectangular_picture.url\" alt=\"Vendor Rectangular Company Icon\" class=\"vendor-icon\" />\n </ng-template>\n\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"img?.id\"\n [resourceData]=\"img\"\n (updated)=\"getPosts.emit()\">\n </pw-resource-edit-card-lazy>\n </ng-container>\n </ng-container>\n </ng-template>\n\n <ng-template #showPostName>\n <ng-container *ngIf=\"img?.showcase; else noLinkTitle\">\n <a class=\"vendor-link\" [href]=\"img.external_url || ('/resources/view/' + img.slug)\">\n <span class=\"vendor-name text-center mt-2\">{{ img?.title }}</span>\n </a>\n </ng-container>\n <ng-template #noLinkTitle>\n <span class=\"vendor-name text-center\">{{ img?.title }}</span>\n </ng-template>\n\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"img?.id\"\n [resourceData]=\"img\"\n (updated)=\"getPosts.emit()\">\n </pw-resource-edit-card-lazy>\n </ng-template>\n </div>\n </div>\n\n <div class=\"customPaginator d-flex align-items-center mt-5 justify-content-center\"\n *ngIf=\"filteredData.length > 0\"\n >\n <p-paginator\n [first]=\"first\"\n [rows]=\"rows\"\n [totalRecords]=\"filteredData.length\"\n (onPageChange)=\"onPageChange($event)\"></p-paginator>\n </div>\n </div>\n</div>\n", styles: [".top-search-input{color:#000!important;border:3px solid #d4d4d4!important;padding:5px 30px!important;border-radius:29px!important}::placeholder{color:#d4d4d4}.vendors-distributor-wrapper{margin-top:5rem!important}.vendor-icon{max-width:180px;max-height:100%;width:100%!important}.vendor-name{font-size:3rem;line-height:3rem;color:var(--text-color, black)}::ng-deep .customPaginator .p-paginator{border:none!important}::ng-deep .customPaginator .p-paginator button{border:none!important}.int-span{text-transform:uppercase;font-size:2.5rem;color:var(--first)}.boxes{width:100%;min-height:150px;display:flex;align-items:center;justify-content:center;text-align:center;padding:15px;border:1px dashed #ccc;border-radius:8px;word-break:break-word;white-space:normal;height:100%}a.vendor-link{display:inline-block;transition:transform .2s ease}a.vendor-link:hover{transform:scale(1.05);cursor:pointer}.search-wrapper{position:relative;width:300px}.search-input{width:100%;padding:10px 20px 10px 40px;border:2px solid #d4d4d4;border-radius:30px;font-size:1rem;color:#000;background-color:#fff}.search-input::placeholder{color:silver}.search-input:focus{outline:none;border-color:var(--first)}.search-icon{position:absolute;top:50%;left:14px;transform:translateY(-50%);color:#d4d4d4;font-size:1.1rem}@media (width <= 768px){.vendor-icon{width:50!important}.search-container{flex-wrap:wrap!important;gap:2rem}.int-span{font-size:1.75rem}}\n"], dependencies: [{ kind: "directive", type: i3$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "directive", type: i8.LazyImgDirective, selector: "img" }, { kind: "component", type: ResourceEditCardLazyComponent, selector: "pw-resource-edit-card-lazy", inputs: ["id", "resourceData", "canEdit"], outputs: ["updated"] }, { kind: "pipe", type: i3$2.SlicePipe, name: "slice" }, { kind: "pipe", type: i10.TranslocoPipe, name: "transloco" }] }); }
880
+ }
881
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceCompanyCardComponent, decorators: [{
882
+ type: Component,
883
+ args: [{ selector: 'pw-resource-company-card', template: "<div [ngClass]=\"{ 'vendors-distributor-wrapper': !vendor }\">\n <div class=\"d-flex justify-content-between align-items-center mb-3 search-container\">\n <div>\n <span class=\"int-span\">{{header}}</span>\n </div>\n <div class=\"search-wrapper position-relative\" *ngIf=\"integrationCountDisplay > 0\">\n <i class=\"fa fa-search search-icon\"></i>\n <input type=\"text\"\n\n (keyup)=\"search($event.target.value)\"\n placeholder=\"Search eg security\"\n class=\"search-input top-search-input\" />\n </div>\n\n </div>\n\n <div *ngIf=\"postData\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n\n <div class=\"row\" *ngIf=\"!postData && integrationCountDisplay > 0\">\n <div class=\"col-md-3 mt-4\"\n *ngFor=\"let img of filteredData | slice:first:(first + rows)\">\n <div class=\"boxes d-flex align-items-center justify-content-center\">\n <ng-container *ngIf=\"img?.companyImg; else checkRectangular\">\n <img [src]=\"img.companyImg\" alt=\"Vendor Company Icon\" class=\"vendor-icon\" />\n </ng-container>\n\n <ng-template #checkRectangular>\n <ng-container *ngIf=\"img?.rectangular_picture?.url; else noImage\">\n <ng-container *ngIf=\"!img.rectangular_picture.url.includes('default-photo'); else showPostName\">\n <ng-container *ngIf=\"img?.showcase; else noLinkImage\">\n <a class=\"vendor-link\" [href]=\"img.external_url || ('/resources/view/' + img.slug)\">\n <img [src]=\"img.rectangular_picture.url\" alt=\"Vendor Rectangular Company Icon\" class=\"vendor-icon\" />\n </a>\n </ng-container>\n <ng-template #noLinkImage>\n <img [src]=\"img.rectangular_picture.url\" alt=\"Vendor Rectangular Company Icon\" class=\"vendor-icon\" />\n </ng-template>\n\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"img?.id\"\n [resourceData]=\"img\"\n (updated)=\"getPosts.emit()\">\n </pw-resource-edit-card-lazy>\n </ng-container>\n </ng-container>\n </ng-template>\n\n <ng-template #showPostName>\n <ng-container *ngIf=\"img?.showcase; else noLinkTitle\">\n <a class=\"vendor-link\" [href]=\"img.external_url || ('/resources/view/' + img.slug)\">\n <span class=\"vendor-name text-center mt-2\">{{ img?.title }}</span>\n </a>\n </ng-container>\n <ng-template #noLinkTitle>\n <span class=\"vendor-name text-center\">{{ img?.title }}</span>\n </ng-template>\n\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"img?.id\"\n [resourceData]=\"img\"\n (updated)=\"getPosts.emit()\">\n </pw-resource-edit-card-lazy>\n </ng-template>\n </div>\n </div>\n\n <div class=\"customPaginator d-flex align-items-center mt-5 justify-content-center\"\n *ngIf=\"filteredData.length > 0\"\n >\n <p-paginator\n [first]=\"first\"\n [rows]=\"rows\"\n [totalRecords]=\"filteredData.length\"\n (onPageChange)=\"onPageChange($event)\"></p-paginator>\n </div>\n </div>\n</div>\n", styles: [".top-search-input{color:#000!important;border:3px solid #d4d4d4!important;padding:5px 30px!important;border-radius:29px!important}::placeholder{color:#d4d4d4}.vendors-distributor-wrapper{margin-top:5rem!important}.vendor-icon{max-width:180px;max-height:100%;width:100%!important}.vendor-name{font-size:3rem;line-height:3rem;color:var(--text-color, black)}::ng-deep .customPaginator .p-paginator{border:none!important}::ng-deep .customPaginator .p-paginator button{border:none!important}.int-span{text-transform:uppercase;font-size:2.5rem;color:var(--first)}.boxes{width:100%;min-height:150px;display:flex;align-items:center;justify-content:center;text-align:center;padding:15px;border:1px dashed #ccc;border-radius:8px;word-break:break-word;white-space:normal;height:100%}a.vendor-link{display:inline-block;transition:transform .2s ease}a.vendor-link:hover{transform:scale(1.05);cursor:pointer}.search-wrapper{position:relative;width:300px}.search-input{width:100%;padding:10px 20px 10px 40px;border:2px solid #d4d4d4;border-radius:30px;font-size:1rem;color:#000;background-color:#fff}.search-input::placeholder{color:silver}.search-input:focus{outline:none;border-color:var(--first)}.search-icon{position:absolute;top:50%;left:14px;transform:translateY(-50%);color:#d4d4d4;font-size:1.1rem}@media (width <= 768px){.vendor-icon{width:50!important}.search-container{flex-wrap:wrap!important;gap:2rem}.int-span{font-size:1.75rem}}\n"] }]
884
+ }], ctorParameters: () => [{ type: i0.Injector }], propDecorators: { getPosts: [{
885
+ type: Output
886
+ }], header: [{
887
+ type: Input
888
+ }], data: [{
889
+ type: Input
890
+ }], integrationCountDisplay: [{
891
+ type: Input
892
+ }], vendor: [{
893
+ type: Input
894
+ }], user: [{
895
+ type: Input
896
+ }], userLoggedIn: [{
897
+ type: Input
898
+ }] } });
899
+
900
+ class ResourceTopBannerEditComponent extends AppBaseComponent {
901
+ constructor(fb, modalService, tagService, injector) {
902
+ super(injector);
903
+ this.fb = fb;
904
+ this.modalService = modalService;
905
+ this.tagService = tagService;
906
+ this.getUpdatedTag = new EventEmitter();
907
+ this.image = null;
908
+ this.defaultImage = 'assets/img/resource/blog.png';
909
+ }
910
+ ngOnInit() {
911
+ if (this.userLoggedIn) {
912
+ this.localStorage.getItem$('product').subscribe(res => {
913
+ const data = res ? JSON.parse(res) : null;
914
+ this.subscriptionId = data?.subscriptionId;
915
+ });
916
+ }
917
+ this.form = this.fb.group({
918
+ title: [this.blogPostTag?.title ?? ''],
919
+ description: [this.blogPostTag?.description ?? ''],
920
+ meta_title: [this.blogPostTag?.meta_title ?? ''],
921
+ meta_description: [this.blogPostTag?.meta_description ?? '']
922
+ });
923
+ this.image = this.blogPostTag?.image?.url ?? null;
924
+ }
925
+ openEditModal() {
926
+ this.modalService.open(this.editModal, { centered: true, size: 'lg' });
927
+ }
928
+ openImageModal(modalRef) {
929
+ this.imageModalRef = this.modalService.open(modalRef, { centered: true });
930
+ }
931
+ onImageSelected(base64) {
932
+ this.image = base64;
933
+ this.file = HelperService.convertBase64ToFile(base64);
934
+ this.imageModalRef?.close();
935
+ }
936
+ onClose() {
937
+ this.imageModalRef?.close();
938
+ }
939
+ removeImage() {
940
+ this.image = null;
941
+ }
942
+ handleImageError(event) {
943
+ event.target.src = this.defaultImage;
944
+ }
945
+ save() {
946
+ this.buttonBusy = true;
947
+ const payload = {
948
+ title: this.form.value.title ?? this.blogPostTag?.title,
949
+ description: this.form.value.description ?? this.blogPostTag?.description,
950
+ meta_title: this.form.value.meta_title ?? this.blogPostTag?.meta_title,
951
+ meta_description: this.form.value.meta_description ?? this.blogPostTag?.meta_description,
952
+ tag_category_id: this.blogPostTag?.tag_category_id,
953
+ tag_type: this.blogPostTag?.tag_type,
954
+ subscription_id: this.subscriptionId,
955
+ name: this.blogPostTag?.name
956
+ };
957
+ if (this.file) {
958
+ payload['image'] = this.file;
959
+ }
960
+ else if (!this.image) {
961
+ payload['remove_image'] = true;
962
+ }
963
+ this.tagService.updateTagById(this.blogPostTag.id, payload).subscribe(() => {
964
+ this.buttonBusy = false;
965
+ this.toast.success('Tag Updated');
966
+ this.getUpdatedTag.emit();
967
+ this.modalService.dismissAll();
968
+ });
969
+ }
970
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceTopBannerEditComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2$1.NgbModal }, { token: i2.TagService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); }
971
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: ResourceTopBannerEditComponent, selector: "pw-resource-top-banner-edit", inputs: { blogPostTag: "blogPostTag", user: "user", userLoggedIn: "userLoggedIn" }, outputs: { getUpdatedTag: "getUpdatedTag" }, viewQueries: [{ propertyName: "editModal", first: true, predicate: ["editModal"], descendants: true }, { propertyName: "imageCropContent", first: true, predicate: ["imageCropContent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"edit-card\">\n <i class=\"fa fa-edit cursor-pointer text-black in-page-edit-icon mb-1 ms-3\"\n (click)=\"openEditModal()\"\n (keydown.enter)=\"openEditModal()\"\n (keydown.space)=\"openEditModal()\"\n title=\"Edit Blog Tag\"></i>\n</div>\n\n <ng-template #editModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit Blog Post Tag</h5>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n\n <div class=\"modal-body\">\n <form [formGroup]=\"form\">\n <div class=\"row\">\n\n <div class=\"col-12\">\n <pw-input-container label=\"Title\" name=\"title\">\n <input type=\"text\" class=\"form-control\" formControlName=\"title\" />\n </pw-input-container>\n </div>\n\n <div class=\"col-12\">\n <pw-input-container label=\"Description\" name=\"description\">\n <textarea class=\"form-control\" rows=\"4\" formControlName=\"description\"></textarea>\n </pw-input-container>\n </div>\n\n <div class=\"col-12\">\n <pw-input-container label=\"Meta Title\" name=\"meta_title\">\n <input type=\"text\" class=\"form-control\" formControlName=\"meta_title\" placeholder=\"Meta Title for SEO\" />\n </pw-input-container>\n </div>\n\n <div class=\"col-12\">\n <pw-input-container label=\"Meta Description\" name=\"meta_description\">\n <textarea class=\"form-control\" rows=\"3\" formControlName=\"meta_description\" placeholder=\"Meta Description for SEO\"></textarea>\n </pw-input-container>\n </div>\n\n <div class=\"col-12 my-4\">\n <label for=\"tagImage\">Blog Tag Image</label>\n <div class=\"text-center d-flex flex-column align-items-center col-6\">\n <img [src]=\"image || defaultImage\"\n (click)=\"openImageModal(imageCropContent)\"\n (keydown.enter)=\"openImageModal(imageCropContent)\"\n (keydown.space)=\"openImageModal(imageCropContent)\"\n class=\"image w-100\"\n alt=\"Blog\"\n (error)=\"handleImageError($event)\"\n />\n <div class=\"d-flex justify-content-between align-items-center mt-2\">\n <a class=\"d-inline-block mt-2\"\n (click)=\"openImageModal(imageCropContent)\">\n {{ image ? 'Update' : 'Add' }} Image\n </a>\n <i *ngIf=\"image\"\n class=\"fa fa-trash delete-icon text-danger ms-2 cursor-pointer\"\n title=\"Remove Image\"\n (keydown.enter)=\"removeImage()\"\n (keydown.space)=\"removeImage()\"\n (click)=\"removeImage()\"></i>\n </div>\n </div>\n </div>\n\n </div>\n </form>\n </div>\n\n <div class=\"modal-footer\">\n <button class=\"btn btn-secondary\" (click)=\"modal.dismiss()\">Cancel</button>\n <button class=\"btn btn-primary\" [buttonBusy]=\"buttonBusy\" (click)=\"save()\">Save</button>\n </div>\n </ng-template>\n\n <ng-template #imageCropContent let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Upload Image</h5>\n <button type=\"button\" class=\"btn-close float-end\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n <div class=\"modal-body\">\n <small>You can upload a JPG, GIF, or PNG file. Avoid artwork, celebrities, or copyrighted images.</small>\n <pw-image-cropper\n #cropper\n aspectRatio=\"dynamic\"\n (imageSelectionEvent)=\"onImageSelected($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n </ng-template>\n", dependencies: [{ kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i6.ProfileImageCropperComponent, selector: "pw-image-cropper", inputs: ["aspectRatio", "dynamicData"], outputs: ["imageSelectionEvent", "closeEvent", "fileChangeEvent"] }, { kind: "component", type: i6.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "directive", type: i8.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i8.LazyImgDirective, selector: "img" }] }); }
972
+ }
973
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceTopBannerEditComponent, decorators: [{
974
+ type: Component,
975
+ args: [{ selector: 'pw-resource-top-banner-edit', template: "<div class=\"edit-card\">\n <i class=\"fa fa-edit cursor-pointer text-black in-page-edit-icon mb-1 ms-3\"\n (click)=\"openEditModal()\"\n (keydown.enter)=\"openEditModal()\"\n (keydown.space)=\"openEditModal()\"\n title=\"Edit Blog Tag\"></i>\n</div>\n\n <ng-template #editModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit Blog Post Tag</h5>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n\n <div class=\"modal-body\">\n <form [formGroup]=\"form\">\n <div class=\"row\">\n\n <div class=\"col-12\">\n <pw-input-container label=\"Title\" name=\"title\">\n <input type=\"text\" class=\"form-control\" formControlName=\"title\" />\n </pw-input-container>\n </div>\n\n <div class=\"col-12\">\n <pw-input-container label=\"Description\" name=\"description\">\n <textarea class=\"form-control\" rows=\"4\" formControlName=\"description\"></textarea>\n </pw-input-container>\n </div>\n\n <div class=\"col-12\">\n <pw-input-container label=\"Meta Title\" name=\"meta_title\">\n <input type=\"text\" class=\"form-control\" formControlName=\"meta_title\" placeholder=\"Meta Title for SEO\" />\n </pw-input-container>\n </div>\n\n <div class=\"col-12\">\n <pw-input-container label=\"Meta Description\" name=\"meta_description\">\n <textarea class=\"form-control\" rows=\"3\" formControlName=\"meta_description\" placeholder=\"Meta Description for SEO\"></textarea>\n </pw-input-container>\n </div>\n\n <div class=\"col-12 my-4\">\n <label for=\"tagImage\">Blog Tag Image</label>\n <div class=\"text-center d-flex flex-column align-items-center col-6\">\n <img [src]=\"image || defaultImage\"\n (click)=\"openImageModal(imageCropContent)\"\n (keydown.enter)=\"openImageModal(imageCropContent)\"\n (keydown.space)=\"openImageModal(imageCropContent)\"\n class=\"image w-100\"\n alt=\"Blog\"\n (error)=\"handleImageError($event)\"\n />\n <div class=\"d-flex justify-content-between align-items-center mt-2\">\n <a class=\"d-inline-block mt-2\"\n (click)=\"openImageModal(imageCropContent)\">\n {{ image ? 'Update' : 'Add' }} Image\n </a>\n <i *ngIf=\"image\"\n class=\"fa fa-trash delete-icon text-danger ms-2 cursor-pointer\"\n title=\"Remove Image\"\n (keydown.enter)=\"removeImage()\"\n (keydown.space)=\"removeImage()\"\n (click)=\"removeImage()\"></i>\n </div>\n </div>\n </div>\n\n </div>\n </form>\n </div>\n\n <div class=\"modal-footer\">\n <button class=\"btn btn-secondary\" (click)=\"modal.dismiss()\">Cancel</button>\n <button class=\"btn btn-primary\" [buttonBusy]=\"buttonBusy\" (click)=\"save()\">Save</button>\n </div>\n </ng-template>\n\n <ng-template #imageCropContent let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Upload Image</h5>\n <button type=\"button\" class=\"btn-close float-end\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n <div class=\"modal-body\">\n <small>You can upload a JPG, GIF, or PNG file. Avoid artwork, celebrities, or copyrighted images.</small>\n <pw-image-cropper\n #cropper\n aspectRatio=\"dynamic\"\n (imageSelectionEvent)=\"onImageSelected($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n </ng-template>\n" }]
976
+ }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i2$1.NgbModal }, { type: i2.TagService }, { type: i0.Injector }], propDecorators: { blogPostTag: [{
977
+ type: Input
978
+ }], user: [{
979
+ type: Input
980
+ }], userLoggedIn: [{
981
+ type: Input
982
+ }], getUpdatedTag: [{
983
+ type: Output
984
+ }], editModal: [{
985
+ type: ViewChild,
986
+ args: ['editModal']
987
+ }], imageCropContent: [{
988
+ type: ViewChild,
989
+ args: ['imageCropContent']
990
+ }] } });
991
+
992
+ class ResourceNoteCardComponent extends AppBaseComponent {
993
+ constructor(injector, resourceService, tagService) {
994
+ super(injector);
995
+ this.resourceService = resourceService;
996
+ this.tagService = tagService;
997
+ this.releaseHeader = false;
998
+ this.isReleasePress = false;
999
+ this.isResource = false;
1000
+ this.postSlice = false;
1001
+ this.canEditResourcesValue = false;
1002
+ this.isLoaded = false;
1003
+ this.masterSubscriptionId = this.appConfig.master_subscription.subscription_id;
1004
+ this.postTags = {};
1005
+ this.releasePosts = {};
1006
+ }
1007
+ ngOnInit() {
1008
+ if (this.userLoggedIn) {
1009
+ this.localStorage.getItem$('product').subscribe(res => {
1010
+ const data = res ? JSON.parse(res) : null;
1011
+ this.subscriptionId = data?.subscriptionId;
1012
+ });
1013
+ }
1014
+ this.getTags();
1015
+ }
1016
+ ngOnChanges(changes) {
1017
+ if (changes['user'] || changes['userLoggedIn']) {
1018
+ if (this.userLoggedIn && this.user) {
1019
+ this.updateCanEditResourcesValue();
1020
+ }
1021
+ }
1022
+ }
1023
+ getTags() {
1024
+ this.isLoaded = false;
1025
+ this.tagService
1026
+ .getAllTagCategories({ search: 'Release Notes' }, this.getEffectiveSubscriptionId())
1027
+ .subscribe(response => {
1028
+ this.tagCategory = response.tag_categories[0];
1029
+ this.getPostTags();
1030
+ });
1031
+ }
1032
+ getPostTags() {
1033
+ this.tagService
1034
+ .getTagsByType('post_categories', {}, this.getEffectiveSubscriptionId())
1035
+ .subscribe(response => {
1036
+ this.postTags['product'] = this.findTag(response.tags, 'Product Release Notes', this.tagCategory?.id);
1037
+ this.postTags['press'] = this.findTag(response.tags, 'Press Release Notes', this.tagCategory?.id);
1038
+ if (this.postTags['product']?.id) {
1039
+ this.getProductReleasePosts(1, 100);
1040
+ }
1041
+ else {
1042
+ this.isLoaded = true;
1043
+ this.releasePosts['product'] = [];
1044
+ }
1045
+ if (this.postTags['press']?.id) {
1046
+ this.getPressReleasePosts(1, 100);
1047
+ }
1048
+ else {
1049
+ this.isLoaded = true;
1050
+ this.releasePosts['press'] = [];
1051
+ }
1052
+ });
1053
+ }
1054
+ findTag(tags, name, categoryId) {
1055
+ return tags.find(tag => tag.name === name && tag.tag_category_id === categoryId);
1056
+ }
1057
+ hasPressReleases() {
1058
+ return this.releasePosts['press']?.length !== 0 && this.isLoaded;
1059
+ }
1060
+ hasProductReleases() {
1061
+ return this.releasePosts['product']?.length !== 0 && this.isLoaded;
1062
+ }
1063
+ getProductReleasePosts(page, pageSize) {
1064
+ this.isLoaded = false;
1065
+ this.resourceService
1066
+ .getPublicPosts(this.getEffectiveSubscriptionId(), page, pageSize, '', '', this.postTags['product']?.id)
1067
+ .subscribe(response => {
1068
+ const sortedPosts = response.posts
1069
+ .filter(post => post.showcase === true)
1070
+ .sort((a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime());
1071
+ this.releasePosts['product'] = this.getProcessedPosts(sortedPosts);
1072
+ })
1073
+ .add(() => {
1074
+ this.isLoaded = true;
1075
+ });
1076
+ }
1077
+ getPressReleasePosts(page, pageSize) {
1078
+ this.isLoaded = false;
1079
+ this.resourceService
1080
+ .getPublicPosts(this.getEffectiveSubscriptionId(), page, pageSize, '', '', this.postTags['press']?.id)
1081
+ .subscribe(response => {
1082
+ const sortedPosts = response?.posts
1083
+ .filter(post => post.showcase === true)
1084
+ .sort((a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime());
1085
+ this.releasePosts['press'] = this.getProcessedPosts(sortedPosts);
1086
+ })
1087
+ .add(() => {
1088
+ this.isLoaded = true;
1089
+ });
1090
+ }
1091
+ getProcessedPosts(posts, sliceCount = 3) {
1092
+ const cloned = [...posts];
1093
+ return this.postSlice ? cloned.reverse() : cloned.slice(0, sliceCount).reverse();
1094
+ }
1095
+ toggleEditTitle() {
1096
+ this.isEditingTitle = true;
1097
+ this.editedTitle = this.postTags['product'].title;
1098
+ }
1099
+ toggleEditPressTitle() {
1100
+ this.isPressEditingTitle = true;
1101
+ this.editedTitle = this.postTags['press'].title;
1102
+ }
1103
+ saveEditedTitle(type) {
1104
+ HelperService.updateTagTitle(this.postTags[type], this.editedTitle, this.tagService, this.getEffectiveSubscriptionId(), this.toast).subscribe(() => {
1105
+ this.postTags[type].title = this.editedTitle;
1106
+ if (type === 'product') {
1107
+ this.isEditingTitle = false;
1108
+ }
1109
+ else {
1110
+ this.isPressEditingTitle = false;
1111
+ }
1112
+ });
1113
+ }
1114
+ /** Helper method to get effective subscription ID */
1115
+ getEffectiveSubscriptionId() {
1116
+ return HelperService.getEffectiveSubscriptionId(this.user, this.subscriptionId, this.masterSubscriptionId);
1117
+ }
1118
+ updateCanEditResourcesValue() {
1119
+ this.canEditResourcesValue = HelperService.canEditResources(this.user, this.userLoggedIn, this.permissionService);
1120
+ }
1121
+ canEditResources() {
1122
+ return this.canEditResourcesValue;
1123
+ }
1124
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceNoteCardComponent, deps: [{ token: i0.Injector }, { token: ResourceService }, { token: i2.TagService }], target: i0.ɵɵFactoryTarget.Component }); }
1125
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: ResourceNoteCardComponent, selector: "pw-resource-note-card", inputs: { releaseHeader: "releaseHeader", categoryId: "categoryId", isReleasePress: "isReleasePress", isResource: "isResource", postSlice: "postSlice", resourceTitle: "resourceTitle", tag: "tag", user: "user", userLoggedIn: "userLoggedIn" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<section class=\"resource-vault-section bg-white\" *ngIf=\"hasProductReleases()\">\n <div class=\"container\">\n <div class=\"d-flex justify-content-between align-items-center flex-wrap\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"postTags['product']?.title; else fallback\" [innerHTML]=\"postTags['product']?.title\"></span>\n <ng-template #fallback>Product Release Notes</ng-template>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleEditTitle()\" (keydown.enter)=\"toggleEditTitle()\" (keydown.space)=\"toggleEditTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle('product')\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n <a class=\"view-all\" *ngIf=\"!postSlice\" routerLink=\"/resources/release-notes\">VIEW ALL ></a>\n </div>\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"releasePosts['product']?.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n <div class=\"row mt-5 d-flex flex-wrap justify-content-center gap-4 video-row\" *ngIf=\"hasProductReleases()\">\n <div class=\"resource-blog-card p-4\" *ngFor=\"let post of releasePosts['product']\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getProductReleasePosts(1, 100)\">\n </pw-resource-edit-card-lazy>\n <p class=\"resource-title\" [innerHTML]=\"post.title\"></p>\n <img *ngIf=\"!post.picture?.url?.includes('default-photo.jpg'); else resourceRocketBox\"\n src=\"{{ post.picture.url }}\"\n class=\"resource-image mt-auto\"\n alt=\"Product Resource Icon\" />\n\n <ng-template #resourceRocketBox>\n <img\n src=\"assets/img/resource/rocket-box.png\"\n class=\"press-release-icon mt-auto\"\n alt=\"Product Resource Default Icon\" />\n </ng-template>\n <ng-template #ctaContent>\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </ng-template>\n <a *ngIf=\"post?.external_url; else internalLink\"\n class=\"resource-btn mt-3\"\n aria-label=\"Navigate to external url\"\n [href]=\"post.external_url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <ng-container *ngTemplateOutlet=\"ctaContent\"></ng-container>\n </a>\n\n <ng-template #internalLink>\n <a class=\"resource-btn mt-3\" aria-label=\"Navigate to resource view\" [routerLink]=\"['/resources/view', post?.slug]\">\n <ng-container *ngTemplateOutlet=\"ctaContent\"></ng-container>\n </a>\n </ng-template>\n </div>\n </div>\n </div>\n</section>\n<section class=\"resource-vault-section bg-white\" *ngIf=\"isReleasePress && hasPressReleases()\">\n <div class=\"container\">\n <div class=\"d-flex justify-content-between align-items-center flex-wrap\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isPressEditingTitle }\">\n <ng-container *ngIf=\"!isPressEditingTitle; else editTitleBlock\">\n <span *ngIf=\"postTags['press']?.title; else fallback\" [innerHTML]=\"postTags['press']?.title\"></span>\n <ng-template #fallback>Press Release Notes</ng-template>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleEditPressTitle()\" (keydown.enter)=\"toggleEditPressTitle()\" (keydown.space)=\"toggleEditPressTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isPressEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle('press')\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isPressEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n <a *ngIf=\"!postSlice\" class=\"view-all\" routerLink=\"/resources/release-notes\">VIEW ALL ></a>\n </div>\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"releasePosts['press']?.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n <div class=\"row mt-5 d-flex flex-wrap justify-content-center gap-4 video-row\" *ngIf=\"hasPressReleases()\">\n <div class=\"resource-blog-card p-4\" *ngFor=\"let post of releasePosts['press']\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getPressReleasePosts(1, 100)\">\n </pw-resource-edit-card-lazy>\n <p class=\"resource-title\" [innerHTML]=\"post.title\"></p>\n <img *ngIf=\"!post.picture?.url.includes('default-photo.jpg'); else resourceRocketBox\"\n src=\"{{ post.picture.url }}\"\n class=\"resource-image mt-auto\"\n alt=\"Press Resource Icon\" />\n\n <ng-template #resourceRocketBox>\n <img\n src=\"assets/img/resource/rocket-box.png\"\n class=\"press-release-icon mt-auto\"\n alt=\"Press Resource Default Icon\" />\n </ng-template>\n <a *ngIf=\"post?.external_url; else internalLink\"\n class=\"resource-btn mt-3\"\n aria-label=\"Navigate to external url\"\n [href]=\"post.external_url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n\n <ng-template #internalLink>\n <a class=\"resource-btn mt-3\" aria-label=\"Navigate to resource view\" [routerLink]=\"['/resources/view', post?.slug]\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n </ng-template>\n </div>\n </div>\n </div>\n</section>\n\n<pw-trial-4-contact-us *ngIf=\"isResource\" [user]=\"user\" [userLoggedIn]=\"userLoggedIn\"></pw-trial-4-contact-us>", styles: [".bold{font-weight:700}.resource-heading{margin-bottom:2rem}.resource-note{margin-top:1rem;font-size:.85rem;color:#555}.resource-divider{border:0;height:40px;width:100%;background:linear-gradient(to bottom,#0000,#00000026);margin:0}.press-release-icon{height:auto!important;margin:0 11px 1.9rem;display:block;align-self:center;width:auto!important;aspect-ratio:0!important;object-fit:cover;margin-top:auto;margin-right:0!important}.resource-vault-section{padding:60px 0;background:#fff;padding-bottom:9rem!important;padding-top:7rem!important;box-shadow:0 4px 32px -14px #40576d4d!important}.resource-vault-section .vault-heading{font-size:3rem;font-weight:300}.resource-vault-section .explore-link{color:#000;font-weight:400;text-decoration:none;font-size:1.5rem}.resource-vault-section .resource-blog-card{display:flex;flex-direction:column;justify-content:space-between;background-color:#fff;border-radius:30px;box-shadow:0 20px 40px #00000014;padding:25px;text-align:center;width:338px;height:auto!important}.resource-vault-section .resource-blog-card h5{font-size:1.5rem;font-weight:400;margin-bottom:.5rem;color:var(--text-color, black)}.resource-vault-section .resource-blog-card p{font-size:1.5rem;color:var(--text-color, black);line-height:2rem}.resource-vault-section .resource-blog-card img{width:100%;border-radius:10px;aspect-ratio:1/1;object-fit:cover;margin-top:auto;margin-right:0!important;max-width:250px!important;align-self:center!important}.resource-vault-section .resource-blog-card iframe{height:210px;border-radius:10px;object-fit:cover;margin-right:0!important;max-width:280px!important}.resource-vault-section .resource-blog-card .resource-btn{background-color:var(--text-color, black);color:#fff;margin-top:auto;padding:10px 24px;border-radius:24px;font-size:1.5rem;font-weight:500;width:100%;max-width:240px;cursor:pointer;transition:background .3s ease;display:flex;justify-content:space-between;align-self:center;align-items:center;text-align:left;text-decoration:none;border:1px solid;box-shadow:none!important;border-color:var(--text-color, black)}.resource-vault-section .resource-blog-card .resource-btn:hover{background:#fff;color:var(--text-color, black)!important}.resource-vault-section .vault-description{text-align:left;max-width:657px;color:#182527;line-height:2.3rem!important;font-size:1.65rem}@media (width <= 1200px){.resource-vault-section .vault-heading{font-size:3.5rem}.resource-vault-section .vault-description{margin-top:1.35rem}.resource-vault-section .resource-btn{margin-left:0!important}}.video-row{gap:5.5rem!important;margin-top:3rem!important}@media (width >= 991px){section.bg-white.text-center.extra-top-padding{position:relative;overflow:hidden}section.bg-white.text-center.extra-top-padding .banner-header{margin-bottom:4rem!important}}.vault-header{text-align:left}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 768px){.video-row{gap:3rem!important}}@media (max-width: 768px){.resource-vault-section{padding-bottom:6rem!important}.resource-vault-section .container{padding-top:0rem!important;padding-bottom:0rem!important}.vault-header{text-align:center!important}.vault-heading{font-size:3rem!important}}@media (width <= 1200px){.container{padding:7rem 3rem 1rem!important}}\n"], dependencies: [{ kind: "directive", type: i3$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i6.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "component", type: i7.ProgressSpinner, selector: "p-progressSpinner", inputs: ["styleClass", "style", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i8.LazyImgDirective, selector: "img" }, { kind: "component", type: Trial4ContactUsComponent, selector: "pw-trial-4-contact-us", inputs: ["subscriptionId", "sourceId", "masterSubscriptionId", "experimentName", "microserviceName", "shardName", "user", "userLoggedIn"] }, { kind: "component", type: ResourceEditCardLazyComponent, selector: "pw-resource-edit-card-lazy", inputs: ["id", "resourceData", "canEdit"], outputs: ["updated"] }, { kind: "pipe", type: i10.TranslocoPipe, name: "transloco" }] }); }
1126
+ }
1127
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceNoteCardComponent, decorators: [{
1128
+ type: Component,
1129
+ args: [{ selector: 'pw-resource-note-card', template: "<section class=\"resource-vault-section bg-white\" *ngIf=\"hasProductReleases()\">\n <div class=\"container\">\n <div class=\"d-flex justify-content-between align-items-center flex-wrap\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"postTags['product']?.title; else fallback\" [innerHTML]=\"postTags['product']?.title\"></span>\n <ng-template #fallback>Product Release Notes</ng-template>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleEditTitle()\" (keydown.enter)=\"toggleEditTitle()\" (keydown.space)=\"toggleEditTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle('product')\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n <a class=\"view-all\" *ngIf=\"!postSlice\" routerLink=\"/resources/release-notes\">VIEW ALL ></a>\n </div>\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"releasePosts['product']?.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n <div class=\"row mt-5 d-flex flex-wrap justify-content-center gap-4 video-row\" *ngIf=\"hasProductReleases()\">\n <div class=\"resource-blog-card p-4\" *ngFor=\"let post of releasePosts['product']\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getProductReleasePosts(1, 100)\">\n </pw-resource-edit-card-lazy>\n <p class=\"resource-title\" [innerHTML]=\"post.title\"></p>\n <img *ngIf=\"!post.picture?.url?.includes('default-photo.jpg'); else resourceRocketBox\"\n src=\"{{ post.picture.url }}\"\n class=\"resource-image mt-auto\"\n alt=\"Product Resource Icon\" />\n\n <ng-template #resourceRocketBox>\n <img\n src=\"assets/img/resource/rocket-box.png\"\n class=\"press-release-icon mt-auto\"\n alt=\"Product Resource Default Icon\" />\n </ng-template>\n <ng-template #ctaContent>\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </ng-template>\n <a *ngIf=\"post?.external_url; else internalLink\"\n class=\"resource-btn mt-3\"\n aria-label=\"Navigate to external url\"\n [href]=\"post.external_url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <ng-container *ngTemplateOutlet=\"ctaContent\"></ng-container>\n </a>\n\n <ng-template #internalLink>\n <a class=\"resource-btn mt-3\" aria-label=\"Navigate to resource view\" [routerLink]=\"['/resources/view', post?.slug]\">\n <ng-container *ngTemplateOutlet=\"ctaContent\"></ng-container>\n </a>\n </ng-template>\n </div>\n </div>\n </div>\n</section>\n<section class=\"resource-vault-section bg-white\" *ngIf=\"isReleasePress && hasPressReleases()\">\n <div class=\"container\">\n <div class=\"d-flex justify-content-between align-items-center flex-wrap\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isPressEditingTitle }\">\n <ng-container *ngIf=\"!isPressEditingTitle; else editTitleBlock\">\n <span *ngIf=\"postTags['press']?.title; else fallback\" [innerHTML]=\"postTags['press']?.title\"></span>\n <ng-template #fallback>Press Release Notes</ng-template>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleEditPressTitle()\" (keydown.enter)=\"toggleEditPressTitle()\" (keydown.space)=\"toggleEditPressTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isPressEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle('press')\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isPressEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n <a *ngIf=\"!postSlice\" class=\"view-all\" routerLink=\"/resources/release-notes\">VIEW ALL ></a>\n </div>\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"releasePosts['press']?.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n <div class=\"row mt-5 d-flex flex-wrap justify-content-center gap-4 video-row\" *ngIf=\"hasPressReleases()\">\n <div class=\"resource-blog-card p-4\" *ngFor=\"let post of releasePosts['press']\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getPressReleasePosts(1, 100)\">\n </pw-resource-edit-card-lazy>\n <p class=\"resource-title\" [innerHTML]=\"post.title\"></p>\n <img *ngIf=\"!post.picture?.url.includes('default-photo.jpg'); else resourceRocketBox\"\n src=\"{{ post.picture.url }}\"\n class=\"resource-image mt-auto\"\n alt=\"Press Resource Icon\" />\n\n <ng-template #resourceRocketBox>\n <img\n src=\"assets/img/resource/rocket-box.png\"\n class=\"press-release-icon mt-auto\"\n alt=\"Press Resource Default Icon\" />\n </ng-template>\n <a *ngIf=\"post?.external_url; else internalLink\"\n class=\"resource-btn mt-3\"\n aria-label=\"Navigate to external url\"\n [href]=\"post.external_url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n\n <ng-template #internalLink>\n <a class=\"resource-btn mt-3\" aria-label=\"Navigate to resource view\" [routerLink]=\"['/resources/view', post?.slug]\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n </ng-template>\n </div>\n </div>\n </div>\n</section>\n\n<pw-trial-4-contact-us *ngIf=\"isResource\" [user]=\"user\" [userLoggedIn]=\"userLoggedIn\"></pw-trial-4-contact-us>", styles: [".bold{font-weight:700}.resource-heading{margin-bottom:2rem}.resource-note{margin-top:1rem;font-size:.85rem;color:#555}.resource-divider{border:0;height:40px;width:100%;background:linear-gradient(to bottom,#0000,#00000026);margin:0}.press-release-icon{height:auto!important;margin:0 11px 1.9rem;display:block;align-self:center;width:auto!important;aspect-ratio:0!important;object-fit:cover;margin-top:auto;margin-right:0!important}.resource-vault-section{padding:60px 0;background:#fff;padding-bottom:9rem!important;padding-top:7rem!important;box-shadow:0 4px 32px -14px #40576d4d!important}.resource-vault-section .vault-heading{font-size:3rem;font-weight:300}.resource-vault-section .explore-link{color:#000;font-weight:400;text-decoration:none;font-size:1.5rem}.resource-vault-section .resource-blog-card{display:flex;flex-direction:column;justify-content:space-between;background-color:#fff;border-radius:30px;box-shadow:0 20px 40px #00000014;padding:25px;text-align:center;width:338px;height:auto!important}.resource-vault-section .resource-blog-card h5{font-size:1.5rem;font-weight:400;margin-bottom:.5rem;color:var(--text-color, black)}.resource-vault-section .resource-blog-card p{font-size:1.5rem;color:var(--text-color, black);line-height:2rem}.resource-vault-section .resource-blog-card img{width:100%;border-radius:10px;aspect-ratio:1/1;object-fit:cover;margin-top:auto;margin-right:0!important;max-width:250px!important;align-self:center!important}.resource-vault-section .resource-blog-card iframe{height:210px;border-radius:10px;object-fit:cover;margin-right:0!important;max-width:280px!important}.resource-vault-section .resource-blog-card .resource-btn{background-color:var(--text-color, black);color:#fff;margin-top:auto;padding:10px 24px;border-radius:24px;font-size:1.5rem;font-weight:500;width:100%;max-width:240px;cursor:pointer;transition:background .3s ease;display:flex;justify-content:space-between;align-self:center;align-items:center;text-align:left;text-decoration:none;border:1px solid;box-shadow:none!important;border-color:var(--text-color, black)}.resource-vault-section .resource-blog-card .resource-btn:hover{background:#fff;color:var(--text-color, black)!important}.resource-vault-section .vault-description{text-align:left;max-width:657px;color:#182527;line-height:2.3rem!important;font-size:1.65rem}@media (width <= 1200px){.resource-vault-section .vault-heading{font-size:3.5rem}.resource-vault-section .vault-description{margin-top:1.35rem}.resource-vault-section .resource-btn{margin-left:0!important}}.video-row{gap:5.5rem!important;margin-top:3rem!important}@media (width >= 991px){section.bg-white.text-center.extra-top-padding{position:relative;overflow:hidden}section.bg-white.text-center.extra-top-padding .banner-header{margin-bottom:4rem!important}}.vault-header{text-align:left}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 768px){.video-row{gap:3rem!important}}@media (max-width: 768px){.resource-vault-section{padding-bottom:6rem!important}.resource-vault-section .container{padding-top:0rem!important;padding-bottom:0rem!important}.vault-header{text-align:center!important}.vault-heading{font-size:3rem!important}}@media (width <= 1200px){.container{padding:7rem 3rem 1rem!important}}\n"] }]
1130
+ }], ctorParameters: () => [{ type: i0.Injector }, { type: ResourceService }, { type: i2.TagService }], propDecorators: { releaseHeader: [{
1131
+ type: Input
1132
+ }], categoryId: [{
1133
+ type: Input
1134
+ }], isReleasePress: [{
1135
+ type: Input
1136
+ }], isResource: [{
1137
+ type: Input
1138
+ }], postSlice: [{
1139
+ type: Input
1140
+ }], resourceTitle: [{
1141
+ type: Input
1142
+ }], tag: [{
1143
+ type: Input
1144
+ }], user: [{
1145
+ type: Input
1146
+ }], userLoggedIn: [{
1147
+ type: Input
1148
+ }] } });
1149
+
1150
+ class CaseStudyCardComponent extends AppBaseComponent {
1151
+ constructor(injector, resourceService, tagService, cdr) {
1152
+ super(injector);
1153
+ this.resourceService = resourceService;
1154
+ this.tagService = tagService;
1155
+ this.cdr = cdr;
1156
+ this.showCaseStudyHeader = false;
1157
+ this.postSlice = false;
1158
+ this.canEditResourcesValue = false;
1159
+ this.isLoaded = false;
1160
+ this.masterSubscriptionId = this.appConfig.master_subscription.subscription_id;
1161
+ this.companyName = this.appConfig.company.name;
1162
+ this.posts = [];
1163
+ this.isEditingTitle = false;
1164
+ }
1165
+ ngOnInit() {
1166
+ if (this.userLoggedIn) {
1167
+ this.localStorage.getItem$('product').subscribe(res => {
1168
+ const data = res ? JSON.parse(res) : null;
1169
+ this.subscriptionId = data?.subscriptionId;
1170
+ });
1171
+ }
1172
+ this.getPosts(1, 10);
1173
+ }
1174
+ ngOnChanges(changes) {
1175
+ if (changes['user'] || changes['userLoggedIn']) {
1176
+ if (this.userLoggedIn && this.user) {
1177
+ this.updateCanEditResourcesValue();
1178
+ }
1179
+ }
1180
+ }
1181
+ getPosts(page, pageSize) {
1182
+ this.isLoaded = false;
1183
+ this.resourceService
1184
+ .getPublicPosts(this.getEffectiveSubscriptionId(), page, pageSize, '', this.categoryId)
1185
+ .subscribe(response => {
1186
+ const sortedPosts = (response.posts ?? [])
1187
+ .filter(post => post.showcase === true)
1188
+ .sort((a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime());
1189
+ this.posts = this.postSlice ? sortedPosts : [...sortedPosts].slice(0, 3);
1190
+ })
1191
+ .add(() => {
1192
+ this.isLoaded = true;
1193
+ this.cdr.markForCheck();
1194
+ });
1195
+ }
1196
+ toggleEditTitle() {
1197
+ this.isEditingTitle = true;
1198
+ this.editedTitle = this.resourceTitle;
1199
+ }
1200
+ saveEditedTitle() {
1201
+ HelperService.updateTagTitle(this.tag, this.editedTitle, this.tagService, this.getEffectiveSubscriptionId(), this.toast).subscribe(() => {
1202
+ this.resourceTitle = this.editedTitle;
1203
+ this.isEditingTitle = false;
1204
+ this.cdr.markForCheck();
1205
+ });
1206
+ }
1207
+ /** Helper method to get effective subscription ID */
1208
+ getEffectiveSubscriptionId() {
1209
+ return HelperService.getEffectiveSubscriptionId(this.user, this.subscriptionId, this.masterSubscriptionId);
1210
+ }
1211
+ updateCanEditResourcesValue() {
1212
+ this.canEditResourcesValue = HelperService.canEditResources(this.user, this.userLoggedIn, this.permissionService);
1213
+ }
1214
+ canEditResources() {
1215
+ return this.canEditResourcesValue;
1216
+ }
1217
+ trackByPostId(index, post) {
1218
+ return post.id;
1219
+ }
1220
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: CaseStudyCardComponent, deps: [{ token: i0.Injector }, { token: ResourceService }, { token: i2.TagService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1221
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: CaseStudyCardComponent, selector: "pw-case-studies-card", inputs: { showCaseStudyHeader: "showCaseStudyHeader", categoryId: "categoryId", postSlice: "postSlice", tag: "tag", resourceTitle: "resourceTitle", user: "user", userLoggedIn: "userLoggedIn" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<section class=\"resource-vault-section bg-white text-center py-5 extra-top-padding section-outer\" id=\"case-studies\">\n <div class=\"container\">\n <ng-container *ngIf=\"showCaseStudyHeader; else fallbackBlock\">\n <div class=\"d-flex justify-content-between align-items-center flex-wrap\">\n <ng-container *ngTemplateOutlet=\"caseStudyHeaderTemplate\"></ng-container>\n <a class=\"view-all\" routerLink=\"/resources/case-studies\">VIEW ALL ></a>\n </div>\n </ng-container>\n\n <ng-template #fallbackBlock>\n <div class=\"d-md-flex justify-content-between align-items-start\">\n <ng-container *ngTemplateOutlet=\"caseStudyHeaderTemplate\"></ng-container>\n </div>\n </ng-template>\n\n <ng-template #caseStudyHeaderTemplate>\n <h2 class=\"section-heading d-flex align-items-center\" id=\"case-studies\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"resourceTitle; else fallback\">\n <span [innerHTML]=\"resourceTitle\"></span>\n </span>\n <ng-template #fallback>Case Studies</ng-template>\n <i *ngIf=\"canEditResourcesValue\"\n class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\"\n (click)=\"toggleEditTitle()\"\n (keydown.enter)=\"toggleEditTitle()\"\n (keydown.space)=\"toggleEditTitle()\"\n title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle()\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n </ng-template>\n\n\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"posts.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n\n\n <div class=\"row d-flex flex-wrap justify-content-center gap-4 video-row\" *ngIf=\"posts.length !== 0 && isLoaded\">\n <div class=\"testimonial-box\" *ngFor=\"let post of posts; trackBy: trackByPostId\">\n\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getPosts(1, 100)\">\n </pw-resource-edit-card-lazy>\n\n <div>\n <img *ngIf=\"!post.rectangular_picture.url.includes('default-photo.jpg') \" [src]=\"post.rectangular_picture.url\"\n alt=\"IT Partners Logo\"\n class=\"company-logo mb-3\"\n loading=\"lazy\" />\n\n <p class=\"mb-4 mt-3 testimonial-section\">\n <span [innerHTML]=\"post.title\"></span>\n </p>\n </div>\n\n <!-- BOTTOM AVATAR -->\n <div class=\"avatar-container mt-5\">\n <img [src]=\"post.picture.url\"\n alt=\"User Avatar\"\n *ngIf=\"post.picture.url && !post.picture.url.includes('default-photo.jpg')\"\n class=\"testimonial-avatar\"\n loading=\"lazy\" />\n <a *ngIf=\"post?.external_url; else internalLink\"\n class=\"read-more-btn-overlay\"\n aria-label=\"Navigate to external url\"\n [href]=\"post.external_url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n\n <ng-template #internalLink>\n <a class=\"read-more-btn-overlay\" aria-label=\"Navigate to resource view\" [routerLink]=\"['/resources/view', post?.slug]\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n</section>\n", styles: [".resource-vault-section{background:#fff;text-align:center;padding:3rem 0}.section-outer,.container{padding:0 15px}.d-md-flex{display:flex}.justify-content-between{justify-content:space-between}.align-items-start{align-items:flex-start}.vault-heading{font-size:2rem;font-weight:700}.video-row{margin-top:3rem;gap:5.5rem!important}.row{display:flex;flex-wrap:wrap}.col-md-6,.col-lg-4{flex:0 0 auto;width:100%}@media (width >= 768px){.col-md-6,.col-lg-4{width:50%}}@media (width >= 992px){.col-md-6,.col-lg-4{width:33.3333%}}.mb-4{margin-bottom:1.5rem}.testimonial-box{display:flex;flex-direction:column;justify-content:space-between;background:#fff;color:#000;border-radius:20px;box-shadow:0 0 20px #0000001a;text-align:center;width:338px;height:auto;padding:2.5rem 1.5rem;font-size:1.1rem;min-height:421.4px!important}.testimonial-box .testimonial-section{font-size:1.5rem;line-height:2rem;font-weight:400;color:var(--text-color, black)}.testimonial-box .testimonial-section strong{display:block}.testimonial-box .company-logo{width:100%!important;height:auto!important;max-width:150px!important;object-fit:contain;align-self:center}.testimonial-box .avatar-container{margin-top:auto;position:relative;display:inline-block}.testimonial-box .avatar-container .testimonial-avatar{width:60%;aspect-ratio:1/1;height:auto;border-radius:50%;object-fit:fill}.testimonial-box .avatar-container .read-more-btn-overlay{position:absolute;text-decoration:none!important;bottom:0;left:50%;transform:translate(-50%);background-color:var(--text-color, black);color:#fff;width:240px;padding:10px 24px;border-radius:24px;font-size:1.5rem;font-weight:500;cursor:pointer;transition:background .3s ease;display:flex;justify-content:space-between;align-items:center;text-align:left;border:1px solid;box-shadow:none!important;border-color:var(--text-color, black)}.testimonial-box .avatar-container .read-more-btn-overlay:hover{background:#fff;color:var(--text-color, black)!important}.testimonial-box .avatar-container .read-more-btn-overlay .arrow{margin-bottom:.3rem}\n"], dependencies: [{ kind: "directive", type: i3$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i6.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "component", type: i7.ProgressSpinner, selector: "p-progressSpinner", inputs: ["styleClass", "style", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i8.LazyImgDirective, selector: "img" }, { kind: "component", type: ResourceEditCardLazyComponent, selector: "pw-resource-edit-card-lazy", inputs: ["id", "resourceData", "canEdit"], outputs: ["updated"] }, { kind: "pipe", type: i10.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1222
+ }
1223
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: CaseStudyCardComponent, decorators: [{
1224
+ type: Component,
1225
+ args: [{ selector: 'pw-case-studies-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section class=\"resource-vault-section bg-white text-center py-5 extra-top-padding section-outer\" id=\"case-studies\">\n <div class=\"container\">\n <ng-container *ngIf=\"showCaseStudyHeader; else fallbackBlock\">\n <div class=\"d-flex justify-content-between align-items-center flex-wrap\">\n <ng-container *ngTemplateOutlet=\"caseStudyHeaderTemplate\"></ng-container>\n <a class=\"view-all\" routerLink=\"/resources/case-studies\">VIEW ALL ></a>\n </div>\n </ng-container>\n\n <ng-template #fallbackBlock>\n <div class=\"d-md-flex justify-content-between align-items-start\">\n <ng-container *ngTemplateOutlet=\"caseStudyHeaderTemplate\"></ng-container>\n </div>\n </ng-template>\n\n <ng-template #caseStudyHeaderTemplate>\n <h2 class=\"section-heading d-flex align-items-center\" id=\"case-studies\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"resourceTitle; else fallback\">\n <span [innerHTML]=\"resourceTitle\"></span>\n </span>\n <ng-template #fallback>Case Studies</ng-template>\n <i *ngIf=\"canEditResourcesValue\"\n class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\"\n (click)=\"toggleEditTitle()\"\n (keydown.enter)=\"toggleEditTitle()\"\n (keydown.space)=\"toggleEditTitle()\"\n title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle()\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n </ng-template>\n\n\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"posts.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n\n\n <div class=\"row d-flex flex-wrap justify-content-center gap-4 video-row\" *ngIf=\"posts.length !== 0 && isLoaded\">\n <div class=\"testimonial-box\" *ngFor=\"let post of posts; trackBy: trackByPostId\">\n\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getPosts(1, 100)\">\n </pw-resource-edit-card-lazy>\n\n <div>\n <img *ngIf=\"!post.rectangular_picture.url.includes('default-photo.jpg') \" [src]=\"post.rectangular_picture.url\"\n alt=\"IT Partners Logo\"\n class=\"company-logo mb-3\"\n loading=\"lazy\" />\n\n <p class=\"mb-4 mt-3 testimonial-section\">\n <span [innerHTML]=\"post.title\"></span>\n </p>\n </div>\n\n <!-- BOTTOM AVATAR -->\n <div class=\"avatar-container mt-5\">\n <img [src]=\"post.picture.url\"\n alt=\"User Avatar\"\n *ngIf=\"post.picture.url && !post.picture.url.includes('default-photo.jpg')\"\n class=\"testimonial-avatar\"\n loading=\"lazy\" />\n <a *ngIf=\"post?.external_url; else internalLink\"\n class=\"read-more-btn-overlay\"\n aria-label=\"Navigate to external url\"\n [href]=\"post.external_url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n\n <ng-template #internalLink>\n <a class=\"read-more-btn-overlay\" aria-label=\"Navigate to resource view\" [routerLink]=\"['/resources/view', post?.slug]\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n</section>\n", styles: [".resource-vault-section{background:#fff;text-align:center;padding:3rem 0}.section-outer,.container{padding:0 15px}.d-md-flex{display:flex}.justify-content-between{justify-content:space-between}.align-items-start{align-items:flex-start}.vault-heading{font-size:2rem;font-weight:700}.video-row{margin-top:3rem;gap:5.5rem!important}.row{display:flex;flex-wrap:wrap}.col-md-6,.col-lg-4{flex:0 0 auto;width:100%}@media (width >= 768px){.col-md-6,.col-lg-4{width:50%}}@media (width >= 992px){.col-md-6,.col-lg-4{width:33.3333%}}.mb-4{margin-bottom:1.5rem}.testimonial-box{display:flex;flex-direction:column;justify-content:space-between;background:#fff;color:#000;border-radius:20px;box-shadow:0 0 20px #0000001a;text-align:center;width:338px;height:auto;padding:2.5rem 1.5rem;font-size:1.1rem;min-height:421.4px!important}.testimonial-box .testimonial-section{font-size:1.5rem;line-height:2rem;font-weight:400;color:var(--text-color, black)}.testimonial-box .testimonial-section strong{display:block}.testimonial-box .company-logo{width:100%!important;height:auto!important;max-width:150px!important;object-fit:contain;align-self:center}.testimonial-box .avatar-container{margin-top:auto;position:relative;display:inline-block}.testimonial-box .avatar-container .testimonial-avatar{width:60%;aspect-ratio:1/1;height:auto;border-radius:50%;object-fit:fill}.testimonial-box .avatar-container .read-more-btn-overlay{position:absolute;text-decoration:none!important;bottom:0;left:50%;transform:translate(-50%);background-color:var(--text-color, black);color:#fff;width:240px;padding:10px 24px;border-radius:24px;font-size:1.5rem;font-weight:500;cursor:pointer;transition:background .3s ease;display:flex;justify-content:space-between;align-items:center;text-align:left;border:1px solid;box-shadow:none!important;border-color:var(--text-color, black)}.testimonial-box .avatar-container .read-more-btn-overlay:hover{background:#fff;color:var(--text-color, black)!important}.testimonial-box .avatar-container .read-more-btn-overlay .arrow{margin-bottom:.3rem}\n"] }]
1226
+ }], ctorParameters: () => [{ type: i0.Injector }, { type: ResourceService }, { type: i2.TagService }, { type: i0.ChangeDetectorRef }], propDecorators: { showCaseStudyHeader: [{
1227
+ type: Input
1228
+ }], categoryId: [{
1229
+ type: Input
1230
+ }], postSlice: [{
1231
+ type: Input
1232
+ }], tag: [{
1233
+ type: Input
1234
+ }], resourceTitle: [{
1235
+ type: Input
1236
+ }], user: [{
1237
+ type: Input
1238
+ }], userLoggedIn: [{
1239
+ type: Input
1240
+ }] } });
1241
+
1242
+ class ResourceCardComponent extends AppBaseComponent {
1243
+ constructor(injector, resourceService, tagService) {
1244
+ super(injector);
1245
+ this.resourceService = resourceService;
1246
+ this.tagService = tagService;
1247
+ this.isHeaderVisible = true;
1248
+ this.isRelated = false;
1249
+ this.postSlice = false;
1250
+ this.isLoaded = false;
1251
+ this.masterSubscriptionId = this.appConfig.master_subscription.subscription_id;
1252
+ this.posts = [];
1253
+ this.canEditResourcesValue = false;
1254
+ }
1255
+ ngOnInit() {
1256
+ if (this.userLoggedIn) {
1257
+ this.localStorage.getItem$('product').subscribe(res => {
1258
+ const data = res ? JSON.parse(res) : null;
1259
+ this.subscriptionId = data?.subscriptionId;
1260
+ });
1261
+ }
1262
+ this.getPosts(1, 10);
1263
+ }
1264
+ ngOnChanges(changes) {
1265
+ if (changes['user'] || changes['userLoggedIn']) {
1266
+ if (this.userLoggedIn && this.user) {
1267
+ this.updateCanEditResourcesValue();
1268
+ }
1269
+ }
1270
+ }
1271
+ getPosts(page, pageSize) {
1272
+ this.isLoaded = false;
1273
+ this.resourceService
1274
+ .getPublicPosts(this.getEffectiveSubscriptionId(), page, pageSize, '', this.categoryId)
1275
+ .subscribe(response => {
1276
+ const sortedPosts = (response.posts ?? [])
1277
+ .filter(post => post.showcase === true)
1278
+ .sort((a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime());
1279
+ this.posts = this.postSlice ? sortedPosts : [...sortedPosts].slice(0, 3);
1280
+ })
1281
+ .add(() => {
1282
+ this.isLoaded = true;
1283
+ });
1284
+ }
1285
+ toggleTagEditTitle() {
1286
+ this.isEditingTitle = true;
1287
+ this.editedTitle = this.resourceTitle;
1288
+ }
1289
+ saveEditedTitle() {
1290
+ HelperService.updateTagTitle(this.tag, this.editedTitle, this.tagService, this.getEffectiveSubscriptionId(), this.toast).subscribe(() => {
1291
+ this.resourceTitle = this.editedTitle;
1292
+ this.isEditingTitle = false;
1293
+ });
1294
+ }
1295
+ /** Helper method to get effective subscription ID */
1296
+ getEffectiveSubscriptionId() {
1297
+ return HelperService.getEffectiveSubscriptionId(this.user, this.subscriptionId, this.masterSubscriptionId);
1298
+ }
1299
+ updateCanEditResourcesValue() {
1300
+ this.canEditResourcesValue = HelperService.canEditResources(this.user, this.userLoggedIn, this.permissionService);
1301
+ }
1302
+ canEditResources() {
1303
+ return this.canEditResourcesValue;
1304
+ }
1305
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceCardComponent, deps: [{ token: i0.Injector }, { token: ResourceService }, { token: i2.TagService }], target: i0.ɵɵFactoryTarget.Component }); }
1306
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: ResourceCardComponent, selector: "pw-resource-cards", inputs: { categoryId: "categoryId", isHeaderVisible: "isHeaderVisible", isRelated: "isRelated", resourceTitle: "resourceTitle", postSlice: "postSlice", header: "header", tag: "tag", resourceLink: "resourceLink", user: "user", userLoggedIn: "userLoggedIn" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<section class=\"resource-vault-section bg-white\">\n <div class=\"container\">\n <div class=\"d-flex justify-content-between align-items-center flex-wrap\" *ngIf=\"isHeaderVisible\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"resourceTitle; else fallback\" [innerHTML]=\"resourceTitle\"></span>\n <ng-template #fallback>Our team\u2019s articles</ng-template>\n <i *ngIf=\"!isRelated && canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleTagEditTitle()\" (keydown.enter)=\"toggleTagEditTitle()\" (keydown.space)=\"toggleTagEditTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle()\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n <a class=\"view-all\" [routerLink]=\"resourceLink\">VIEW ALL ></a>\n </div>\n\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"posts.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n\n <div class=\"row d-flex flex-wrap justify-content-center gap-4 video-row\" *ngIf=\"posts.length !== 0 && isLoaded\">\n <div class=\"resource-blog-card p-4\" *ngFor=\"let post of posts\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getPosts(1, 100)\">\n </pw-resource-edit-card-lazy>\n <p class=\"resource-title\" [innerHTML]=\"post.title \"></p>\n <a\n [href]=\"post.external_url || ('/resources/view/' + post?.slug)\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Navigate to resource\"\n >\n <img\n [src]=\"post.picture.url\"\n class=\"img-fluid my-3 mt-auto\"\n alt=\"Webinar\"\n /></a>\n <a *ngIf=\"post?.external_url; else internalLink\"\n class=\"resource-btn mt-3\"\n [href]=\"post.external_url\"\n aria-label=\"Navigate to external url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n\n <ng-template #internalLink>\n <a class=\"resource-btn mt-3\" aria-label=\"Navigate to resource view\" [href]=\"'/resources/view/' + post?.slug\" target=\"_blank\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n </ng-template>\n </div>\n </div>\n </div>\n </section>", styles: [".bold{font-weight:700}.resource-heading{margin-bottom:2rem}.resource-note{margin-top:1rem;font-size:.85rem;color:#555}.resource-divider{border:0;height:40px;width:100%;background:linear-gradient(to bottom,#0000,#00000026);margin:0}.press-release-icon{height:auto!important;margin:0 11px 1.9rem;display:block;align-self:center;width:auto!important;aspect-ratio:0!important;object-fit:cover;margin-top:auto;margin-right:0!important}.resource-vault-section{padding:60px 0;background:#fff;padding-bottom:9rem!important;padding-top:7rem!important;box-shadow:0 4px 32px -14px #40576d4d!important}.resource-vault-section .vault-heading{font-size:3rem;font-weight:300}.resource-vault-section .explore-link{color:#000;font-weight:400;text-decoration:none;font-size:1.5rem}.resource-vault-section .resource-blog-card{display:flex;flex-direction:column;justify-content:space-between;background-color:#fff;border-radius:30px;box-shadow:0 20px 40px #00000014;padding:25px;text-align:center;width:338px;height:auto!important}.resource-vault-section .resource-blog-card h5{font-size:1.5rem;font-weight:400;margin-bottom:.5rem;color:var(--text-color, black)}.resource-vault-section .resource-blog-card p{font-size:1.5rem;color:var(--text-color, black);line-height:2rem}.resource-vault-section .resource-blog-card img{width:100%;border-radius:10px;aspect-ratio:1/1;object-fit:cover;margin-top:auto;margin-right:0!important;max-width:250px!important;align-self:center!important}.resource-vault-section .resource-blog-card iframe{height:210px;border-radius:10px;object-fit:cover;margin-right:0!important;max-width:280px!important}.resource-vault-section .resource-blog-card .resource-btn{background-color:var(--text-color, black);color:#fff;margin-top:auto;padding:10px 24px;border-radius:24px;font-size:1.5rem;font-weight:500;width:100%;max-width:240px;cursor:pointer;transition:background .3s ease;display:flex;justify-content:space-between;align-self:center;align-items:center;text-align:left;text-decoration:none;border:1px solid;box-shadow:none!important;border-color:var(--text-color, black)}.resource-vault-section .resource-blog-card .resource-btn:hover{background:#fff;color:var(--text-color, black)!important}.resource-vault-section .vault-description{text-align:left;max-width:657px;color:#182527;line-height:2.3rem!important;font-size:1.65rem}@media (width <= 1200px){.resource-vault-section .vault-heading{font-size:3.5rem}.resource-vault-section .vault-description{margin-top:1.35rem}.resource-vault-section .resource-btn{margin-left:0!important}}.video-row{gap:5.5rem!important;margin-top:3rem!important}@media (width >= 991px){section.bg-white.text-center.extra-top-padding{position:relative;overflow:hidden}section.bg-white.text-center.extra-top-padding .banner-header{margin-bottom:4rem!important}}.vault-header{text-align:left}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 768px){.video-row{gap:3rem!important}}@media (max-width: 768px){.resource-vault-section{padding-bottom:6rem!important}.resource-vault-section .container{padding-top:0rem!important;padding-bottom:0rem!important}.vault-header{text-align:center!important}.vault-heading{font-size:3rem!important}}@media (width <= 1200px){.container{padding:7rem 3rem 1rem!important}}\n"], dependencies: [{ kind: "directive", type: i3$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i6.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "component", type: i7.ProgressSpinner, selector: "p-progressSpinner", inputs: ["styleClass", "style", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i8.LazyImgDirective, selector: "img" }, { kind: "component", type: ResourceEditCardLazyComponent, selector: "pw-resource-edit-card-lazy", inputs: ["id", "resourceData", "canEdit"], outputs: ["updated"] }, { kind: "pipe", type: i10.TranslocoPipe, name: "transloco" }] }); }
1307
+ }
1308
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceCardComponent, decorators: [{
1309
+ type: Component,
1310
+ args: [{ selector: 'pw-resource-cards', template: "<section class=\"resource-vault-section bg-white\">\n <div class=\"container\">\n <div class=\"d-flex justify-content-between align-items-center flex-wrap\" *ngIf=\"isHeaderVisible\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"resourceTitle; else fallback\" [innerHTML]=\"resourceTitle\"></span>\n <ng-template #fallback>Our team\u2019s articles</ng-template>\n <i *ngIf=\"!isRelated && canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleTagEditTitle()\" (keydown.enter)=\"toggleTagEditTitle()\" (keydown.space)=\"toggleTagEditTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle()\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n <a class=\"view-all\" [routerLink]=\"resourceLink\">VIEW ALL ></a>\n </div>\n\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"posts.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n\n <div class=\"row d-flex flex-wrap justify-content-center gap-4 video-row\" *ngIf=\"posts.length !== 0 && isLoaded\">\n <div class=\"resource-blog-card p-4\" *ngFor=\"let post of posts\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getPosts(1, 100)\">\n </pw-resource-edit-card-lazy>\n <p class=\"resource-title\" [innerHTML]=\"post.title \"></p>\n <a\n [href]=\"post.external_url || ('/resources/view/' + post?.slug)\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Navigate to resource\"\n >\n <img\n [src]=\"post.picture.url\"\n class=\"img-fluid my-3 mt-auto\"\n alt=\"Webinar\"\n /></a>\n <a *ngIf=\"post?.external_url; else internalLink\"\n class=\"resource-btn mt-3\"\n [href]=\"post.external_url\"\n aria-label=\"Navigate to external url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n\n <ng-template #internalLink>\n <a class=\"resource-btn mt-3\" aria-label=\"Navigate to resource view\" [href]=\"'/resources/view/' + post?.slug\" target=\"_blank\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n </ng-template>\n </div>\n </div>\n </div>\n </section>", styles: [".bold{font-weight:700}.resource-heading{margin-bottom:2rem}.resource-note{margin-top:1rem;font-size:.85rem;color:#555}.resource-divider{border:0;height:40px;width:100%;background:linear-gradient(to bottom,#0000,#00000026);margin:0}.press-release-icon{height:auto!important;margin:0 11px 1.9rem;display:block;align-self:center;width:auto!important;aspect-ratio:0!important;object-fit:cover;margin-top:auto;margin-right:0!important}.resource-vault-section{padding:60px 0;background:#fff;padding-bottom:9rem!important;padding-top:7rem!important;box-shadow:0 4px 32px -14px #40576d4d!important}.resource-vault-section .vault-heading{font-size:3rem;font-weight:300}.resource-vault-section .explore-link{color:#000;font-weight:400;text-decoration:none;font-size:1.5rem}.resource-vault-section .resource-blog-card{display:flex;flex-direction:column;justify-content:space-between;background-color:#fff;border-radius:30px;box-shadow:0 20px 40px #00000014;padding:25px;text-align:center;width:338px;height:auto!important}.resource-vault-section .resource-blog-card h5{font-size:1.5rem;font-weight:400;margin-bottom:.5rem;color:var(--text-color, black)}.resource-vault-section .resource-blog-card p{font-size:1.5rem;color:var(--text-color, black);line-height:2rem}.resource-vault-section .resource-blog-card img{width:100%;border-radius:10px;aspect-ratio:1/1;object-fit:cover;margin-top:auto;margin-right:0!important;max-width:250px!important;align-self:center!important}.resource-vault-section .resource-blog-card iframe{height:210px;border-radius:10px;object-fit:cover;margin-right:0!important;max-width:280px!important}.resource-vault-section .resource-blog-card .resource-btn{background-color:var(--text-color, black);color:#fff;margin-top:auto;padding:10px 24px;border-radius:24px;font-size:1.5rem;font-weight:500;width:100%;max-width:240px;cursor:pointer;transition:background .3s ease;display:flex;justify-content:space-between;align-self:center;align-items:center;text-align:left;text-decoration:none;border:1px solid;box-shadow:none!important;border-color:var(--text-color, black)}.resource-vault-section .resource-blog-card .resource-btn:hover{background:#fff;color:var(--text-color, black)!important}.resource-vault-section .vault-description{text-align:left;max-width:657px;color:#182527;line-height:2.3rem!important;font-size:1.65rem}@media (width <= 1200px){.resource-vault-section .vault-heading{font-size:3.5rem}.resource-vault-section .vault-description{margin-top:1.35rem}.resource-vault-section .resource-btn{margin-left:0!important}}.video-row{gap:5.5rem!important;margin-top:3rem!important}@media (width >= 991px){section.bg-white.text-center.extra-top-padding{position:relative;overflow:hidden}section.bg-white.text-center.extra-top-padding .banner-header{margin-bottom:4rem!important}}.vault-header{text-align:left}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 768px){.video-row{gap:3rem!important}}@media (max-width: 768px){.resource-vault-section{padding-bottom:6rem!important}.resource-vault-section .container{padding-top:0rem!important;padding-bottom:0rem!important}.vault-header{text-align:center!important}.vault-heading{font-size:3rem!important}}@media (width <= 1200px){.container{padding:7rem 3rem 1rem!important}}\n"] }]
1311
+ }], ctorParameters: () => [{ type: i0.Injector }, { type: ResourceService }, { type: i2.TagService }], propDecorators: { categoryId: [{
1312
+ type: Input
1313
+ }], isHeaderVisible: [{
1314
+ type: Input
1315
+ }], isRelated: [{
1316
+ type: Input
1317
+ }], resourceTitle: [{
1318
+ type: Input
1319
+ }], postSlice: [{
1320
+ type: Input
1321
+ }], header: [{
1322
+ type: Input
1323
+ }], tag: [{
1324
+ type: Input
1325
+ }], resourceLink: [{
1326
+ type: Input
1327
+ }], user: [{
1328
+ type: Input
1329
+ }], userLoggedIn: [{
1330
+ type: Input
1331
+ }] } });
1332
+
1333
+ class BaseResourceComponent extends AppBaseComponent {
1334
+ constructor(resourceService, tagService, authService, injector) {
1335
+ super(injector);
1336
+ this.resourceService = resourceService;
1337
+ this.tagService = tagService;
1338
+ this.authService = authService;
1339
+ this.masterSubscriptionId = this.appConfig.master_subscription.subscription_id;
1340
+ this.posts = [];
1341
+ this.testimonialsPosts = [];
1342
+ this.isLoaded = false;
1343
+ this.canEditResourcesValue = false;
1344
+ }
1345
+ ngOnInit() {
1346
+ this.getUserSubscriptionId().subscribe(response => {
1347
+ this.subscriptionId = response;
1348
+ });
1349
+ this.authService.getToken$().subscribe(res => {
1350
+ this.userLoggedIn = !!res;
1351
+ if (this.userLoggedIn) {
1352
+ this.localStorage.getItem$('product').subscribe(res => {
1353
+ const data = res ? JSON.parse(res) : null;
1354
+ this.subscriptionId = data?.subscriptionId;
1355
+ });
1356
+ this.userService.getUserInfo().subscribe(data => {
1357
+ this.user = data;
1358
+ this.updateCanEditResourcesValue();
1359
+ this.initializeComponent();
1360
+ });
1361
+ }
1362
+ else {
1363
+ this.initializeComponent();
1364
+ }
1365
+ });
1366
+ }
1367
+ initializeComponent() {
1368
+ if (this.shouldUseTagCategories()) {
1369
+ this.getTags();
1370
+ }
1371
+ else {
1372
+ this.getPostTags();
1373
+ }
1374
+ if (this.shouldLoadTestimonials()) {
1375
+ this.getTestimonialTags();
1376
+ }
1377
+ }
1378
+ getTags() {
1379
+ this.isLoaded = false;
1380
+ this.tagService
1381
+ .getAllTagCategories({ search: this.getSearchTerm() }, this.getEffectiveSubscriptionId())
1382
+ .subscribe(response => {
1383
+ this.tagCategory = response.tag_categories[0];
1384
+ this.getPostTags();
1385
+ });
1386
+ }
1387
+ getPostTags() {
1388
+ this.tagService
1389
+ .getTagsByType('post_categories', {}, this.getEffectiveSubscriptionId())
1390
+ .subscribe(response => {
1391
+ if (this.shouldUseTagCategories()) {
1392
+ this.blogPostTag = response.tags.find(tag => tag.tag_category_id === this.tagCategory?.id);
1393
+ }
1394
+ else {
1395
+ this.blogPostTag = response.tags.find(tag => tag.name === this.getResourceType());
1396
+ }
1397
+ this.getPosts(1, 100);
1398
+ })
1399
+ .add(() => {
1400
+ this.isLoaded = true;
1401
+ });
1402
+ }
1403
+ getTestimonialTags() {
1404
+ this.tagService
1405
+ .getTagsByType('post_categories', {}, this.getEffectiveSubscriptionId())
1406
+ .subscribe(response => {
1407
+ this.blogTestimonialsPostTag = response.tags.find(tag => tag.name === 'Testimonials');
1408
+ this.getTestimonialsPosts(1, 100);
1409
+ });
1410
+ }
1411
+ getPosts(page, pageSize) {
1412
+ this.fetchPosts(page, pageSize, this.blogPostTag?.tag_category_id, 'posts');
1413
+ }
1414
+ getTestimonialsPosts(page, pageSize) {
1415
+ this.fetchPosts(page, pageSize, this.blogTestimonialsPostTag?.tag_category_id, 'testimonialsPosts');
1416
+ }
1417
+ /** Shared method to fetch posts with common filtering, sorting, and slicing logic */
1418
+ fetchPosts(page, pageSize, tagCategoryId, targetProperty) {
1419
+ this.resourceService
1420
+ .getPublicPosts(this.getEffectiveSubscriptionId(), page, pageSize, '', tagCategoryId)
1421
+ .subscribe(response => {
1422
+ const filteredPosts = response.posts
1423
+ .filter(post => post.tags?.some(tag => tag.tag_category_id === tagCategoryId))
1424
+ .sort((a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime())
1425
+ .slice(0, 12);
1426
+ if (targetProperty === 'posts') {
1427
+ this.posts = filteredPosts;
1428
+ }
1429
+ else {
1430
+ this.testimonialsPosts = filteredPosts;
1431
+ }
1432
+ });
1433
+ }
1434
+ /** Helper method to get effective subscription ID */
1435
+ getEffectiveSubscriptionId() {
1436
+ return HelperService.getEffectiveSubscriptionId(this.user, this.subscriptionId, this.masterSubscriptionId);
1437
+ }
1438
+ // Optional methods that can be overridden
1439
+ getSearchTerm() {
1440
+ return this.getResourceType();
1441
+ }
1442
+ shouldUseTagCategories() {
1443
+ return false;
1444
+ }
1445
+ shouldLoadTestimonials() {
1446
+ return false;
1447
+ }
1448
+ updateCanEditResourcesValue() {
1449
+ if (this.userLoggedIn && this.user) {
1450
+ this.canEditResourcesValue = HelperService.canEditResources(this.user, this.userLoggedIn, this.permissionService);
1451
+ }
1452
+ else {
1453
+ this.canEditResourcesValue = false;
1454
+ }
1455
+ }
1456
+ canEditResources() {
1457
+ return this.canEditResourcesValue;
1458
+ }
1459
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: BaseResourceComponent, deps: [{ token: ResourceService }, { token: i2.TagService }, { token: i2.AuthService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); }
1460
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: BaseResourceComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: '', isInline: true }); }
1461
+ }
1462
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: BaseResourceComponent, decorators: [{
1463
+ type: Component,
1464
+ args: [{
1465
+ template: ''
1466
+ }]
1467
+ }], ctorParameters: () => [{ type: ResourceService }, { type: i2.TagService }, { type: i2.AuthService }, { type: i0.Injector }] });
1468
+
1469
+ class ResourceVaultComponent extends BaseResourceComponent {
1470
+ constructor(resourceService, tagService, authService, injector) {
1471
+ super(resourceService, tagService, authService, injector);
1472
+ this.showVaultSection = false;
1473
+ this.postSlice = false;
1474
+ this.isEditingTitle = false;
1475
+ }
1476
+ ngOnInit() {
1477
+ super.ngOnInit();
1478
+ this.getPosts(1, 10);
1479
+ }
1480
+ getResourceType() {
1481
+ return 'Vault';
1482
+ }
1483
+ getPosts(page, pageSize) {
1484
+ this.isLoaded = false;
1485
+ this.resourceService
1486
+ .getPublicPosts(this.getEffectiveSubscriptionId(), page, pageSize, '', this.categoryId)
1487
+ .subscribe(response => {
1488
+ const sortedPosts = (response.posts ?? [])
1489
+ .filter(post => post.showcase === true)
1490
+ .sort((a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime());
1491
+ this.posts = this.postSlice ? sortedPosts : [...sortedPosts].slice(0, 3);
1492
+ })
1493
+ .add(() => {
1494
+ this.isLoaded = true;
1495
+ });
1496
+ }
1497
+ toggleEditTitle() {
1498
+ this.isEditingTitle = true;
1499
+ this.editedTitle = this.resourceTitle;
1500
+ }
1501
+ saveEditedTitle() {
1502
+ HelperService.updateTagTitle(this.tag, this.editedTitle, this.tagService, this.getEffectiveSubscriptionId(), this.toast).subscribe(() => {
1503
+ this.resourceTitle = this.editedTitle;
1504
+ this.isEditingTitle = false;
1505
+ });
1506
+ }
1507
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceVaultComponent, deps: [{ token: ResourceService }, { token: i2.TagService }, { token: i2.AuthService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); }
1508
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: ResourceVaultComponent, selector: "pw-resource--vault", inputs: { showVaultSection: "showVaultSection", postSlice: "postSlice", categoryId: "categoryId", resourceTitle: "resourceTitle", tag: "tag" }, usesInheritance: true, ngImport: i0, template: "<section class=\"resource-vault-section bg-white text-center py-5 extra-top-padding section-outer\">\n <div class=\"container\">\n <div *ngIf=\"showVaultSection\" class=\"d-flex justify-content-between align-items-center flex-wrap mb-5\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"resourceTitle; else fallback\" [innerHTML]=\"resourceTitle\"></span>\n <ng-template #fallback>Whitepapers &amp; Tools</ng-template>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleEditTitle()\" (keydown.enter)=\"toggleEditTitle()\" (keydown.space)=\"toggleEditTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle()\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n\n <a class=\"view-all\" routerLink=\"/resources/white-papers\">VIEW ALL ></a>\n </div>\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"posts.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n <div class=\"d-flex mt-2 flex-wrap justify-content-center gap-4 video-row\" *ngIf=\"posts.length !== 0 && isLoaded\">\n <div class=\"resource-blog-card text-center p-4\" *ngFor=\"let post of posts\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getPosts(1, 100)\">\n </pw-resource-edit-card-lazy>\n <p class=\"mb-4\" [innerHTML]=\"post.title\"></p>\n <a\n [href]=\"post.external_url || ('/resources/view/' + post?.slug)\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Navigate to resource\"\n >\n <img\n [src]=\"post.picture.url\"\n class=\"img-fluid my-3 mt-auto\"\n alt=\"Webinar\"\n loading=\"lazy\"\n />\n </a>\n <a *ngIf=\"post?.external_url; else internalLink\"\n class=\"resource-btn mt-3\"\n aria-label=\"Navigate to external url\"\n [href]=\"post.external_url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n\n <ng-template #internalLink>\n <a class=\"resource-btn mt-3\" aria-label=\"Navigate to resource view\" [href]=\"'/resources/view/' + post?.slug\" target=\"_blank\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n </ng-template>\n </div>\n </div>\n </div>\n</section>\n", styles: [".bold{font-weight:700}.resource-heading{margin-bottom:2rem}.resource-note{margin-top:1rem;font-size:.85rem;color:#555}.resource-divider{border:0;height:40px;width:100%;background:linear-gradient(to bottom,#0000,#00000026);margin:0}.press-release-icon{height:auto!important;margin:0 11px 1.9rem;display:block;align-self:center;width:auto!important;aspect-ratio:0!important;object-fit:cover;margin-top:auto;margin-right:0!important}.resource-vault-section{padding:60px 0;background:#fff;padding-bottom:9rem!important;padding-top:7rem!important;box-shadow:0 4px 32px -14px #40576d4d!important}.resource-vault-section .vault-heading{font-size:3rem;font-weight:300}.resource-vault-section .explore-link{color:#000;font-weight:400;text-decoration:none;font-size:1.5rem}.resource-vault-section .resource-blog-card{display:flex;flex-direction:column;justify-content:space-between;background-color:#fff;border-radius:30px;box-shadow:0 20px 40px #00000014;padding:25px;text-align:center;width:338px;height:auto!important}.resource-vault-section .resource-blog-card h5{font-size:1.5rem;font-weight:400;margin-bottom:.5rem;color:var(--text-color, black)}.resource-vault-section .resource-blog-card p{font-size:1.5rem;color:var(--text-color, black);line-height:2rem}.resource-vault-section .resource-blog-card img{width:100%;border-radius:10px;aspect-ratio:1/1;object-fit:cover;margin-top:auto;margin-right:0!important;max-width:250px!important;align-self:center!important}.resource-vault-section .resource-blog-card iframe{height:210px;border-radius:10px;object-fit:cover;margin-right:0!important;max-width:280px!important}.resource-vault-section .resource-blog-card .resource-btn{background-color:var(--text-color, black);color:#fff;margin-top:auto;padding:10px 24px;border-radius:24px;font-size:1.5rem;font-weight:500;width:100%;max-width:240px;cursor:pointer;transition:background .3s ease;display:flex;justify-content:space-between;align-self:center;align-items:center;text-align:left;text-decoration:none;border:1px solid;box-shadow:none!important;border-color:var(--text-color, black)}.resource-vault-section .resource-blog-card .resource-btn:hover{background:#fff;color:var(--text-color, black)!important}.resource-vault-section .vault-description{text-align:left;max-width:657px;color:#182527;line-height:2.3rem!important;font-size:1.65rem}@media (width <= 1200px){.resource-vault-section .vault-heading{font-size:3.5rem}.resource-vault-section .vault-description{margin-top:1.35rem}.resource-vault-section .resource-btn{margin-left:0!important}}.video-row{gap:5.5rem!important;margin-top:3rem!important}@media (width >= 991px){section.bg-white.text-center.extra-top-padding{position:relative;overflow:hidden}section.bg-white.text-center.extra-top-padding .banner-header{margin-bottom:4rem!important}}.vault-header{text-align:left}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 768px){.video-row{gap:3rem!important}}@media (max-width: 768px){.resource-vault-section{padding-bottom:6rem!important}.resource-vault-section .container{padding-top:0rem!important;padding-bottom:0rem!important}.vault-header{text-align:center!important}.vault-heading{font-size:3rem!important}}@media (width <= 1200px){.container{padding:7rem 3rem 1rem!important}}\n"], dependencies: [{ kind: "directive", type: i3$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i6.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "component", type: i7.ProgressSpinner, selector: "p-progressSpinner", inputs: ["styleClass", "style", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i8.LazyImgDirective, selector: "img" }, { kind: "component", type: ResourceEditCardLazyComponent, selector: "pw-resource-edit-card-lazy", inputs: ["id", "resourceData", "canEdit"], outputs: ["updated"] }, { kind: "pipe", type: i10.TranslocoPipe, name: "transloco" }] }); }
1509
+ }
1510
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceVaultComponent, decorators: [{
1511
+ type: Component,
1512
+ args: [{ selector: 'pw-resource--vault', template: "<section class=\"resource-vault-section bg-white text-center py-5 extra-top-padding section-outer\">\n <div class=\"container\">\n <div *ngIf=\"showVaultSection\" class=\"d-flex justify-content-between align-items-center flex-wrap mb-5\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"resourceTitle; else fallback\" [innerHTML]=\"resourceTitle\"></span>\n <ng-template #fallback>Whitepapers &amp; Tools</ng-template>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleEditTitle()\" (keydown.enter)=\"toggleEditTitle()\" (keydown.space)=\"toggleEditTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle()\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n\n <a class=\"view-all\" routerLink=\"/resources/white-papers\">VIEW ALL ></a>\n </div>\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"posts.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n <div class=\"d-flex mt-2 flex-wrap justify-content-center gap-4 video-row\" *ngIf=\"posts.length !== 0 && isLoaded\">\n <div class=\"resource-blog-card text-center p-4\" *ngFor=\"let post of posts\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getPosts(1, 100)\">\n </pw-resource-edit-card-lazy>\n <p class=\"mb-4\" [innerHTML]=\"post.title\"></p>\n <a\n [href]=\"post.external_url || ('/resources/view/' + post?.slug)\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Navigate to resource\"\n >\n <img\n [src]=\"post.picture.url\"\n class=\"img-fluid my-3 mt-auto\"\n alt=\"Webinar\"\n loading=\"lazy\"\n />\n </a>\n <a *ngIf=\"post?.external_url; else internalLink\"\n class=\"resource-btn mt-3\"\n aria-label=\"Navigate to external url\"\n [href]=\"post.external_url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n\n <ng-template #internalLink>\n <a class=\"resource-btn mt-3\" aria-label=\"Navigate to resource view\" [href]=\"'/resources/view/' + post?.slug\" target=\"_blank\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n </ng-template>\n </div>\n </div>\n </div>\n</section>\n", styles: [".bold{font-weight:700}.resource-heading{margin-bottom:2rem}.resource-note{margin-top:1rem;font-size:.85rem;color:#555}.resource-divider{border:0;height:40px;width:100%;background:linear-gradient(to bottom,#0000,#00000026);margin:0}.press-release-icon{height:auto!important;margin:0 11px 1.9rem;display:block;align-self:center;width:auto!important;aspect-ratio:0!important;object-fit:cover;margin-top:auto;margin-right:0!important}.resource-vault-section{padding:60px 0;background:#fff;padding-bottom:9rem!important;padding-top:7rem!important;box-shadow:0 4px 32px -14px #40576d4d!important}.resource-vault-section .vault-heading{font-size:3rem;font-weight:300}.resource-vault-section .explore-link{color:#000;font-weight:400;text-decoration:none;font-size:1.5rem}.resource-vault-section .resource-blog-card{display:flex;flex-direction:column;justify-content:space-between;background-color:#fff;border-radius:30px;box-shadow:0 20px 40px #00000014;padding:25px;text-align:center;width:338px;height:auto!important}.resource-vault-section .resource-blog-card h5{font-size:1.5rem;font-weight:400;margin-bottom:.5rem;color:var(--text-color, black)}.resource-vault-section .resource-blog-card p{font-size:1.5rem;color:var(--text-color, black);line-height:2rem}.resource-vault-section .resource-blog-card img{width:100%;border-radius:10px;aspect-ratio:1/1;object-fit:cover;margin-top:auto;margin-right:0!important;max-width:250px!important;align-self:center!important}.resource-vault-section .resource-blog-card iframe{height:210px;border-radius:10px;object-fit:cover;margin-right:0!important;max-width:280px!important}.resource-vault-section .resource-blog-card .resource-btn{background-color:var(--text-color, black);color:#fff;margin-top:auto;padding:10px 24px;border-radius:24px;font-size:1.5rem;font-weight:500;width:100%;max-width:240px;cursor:pointer;transition:background .3s ease;display:flex;justify-content:space-between;align-self:center;align-items:center;text-align:left;text-decoration:none;border:1px solid;box-shadow:none!important;border-color:var(--text-color, black)}.resource-vault-section .resource-blog-card .resource-btn:hover{background:#fff;color:var(--text-color, black)!important}.resource-vault-section .vault-description{text-align:left;max-width:657px;color:#182527;line-height:2.3rem!important;font-size:1.65rem}@media (width <= 1200px){.resource-vault-section .vault-heading{font-size:3.5rem}.resource-vault-section .vault-description{margin-top:1.35rem}.resource-vault-section .resource-btn{margin-left:0!important}}.video-row{gap:5.5rem!important;margin-top:3rem!important}@media (width >= 991px){section.bg-white.text-center.extra-top-padding{position:relative;overflow:hidden}section.bg-white.text-center.extra-top-padding .banner-header{margin-bottom:4rem!important}}.vault-header{text-align:left}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 768px){.video-row{gap:3rem!important}}@media (max-width: 768px){.resource-vault-section{padding-bottom:6rem!important}.resource-vault-section .container{padding-top:0rem!important;padding-bottom:0rem!important}.vault-header{text-align:center!important}.vault-heading{font-size:3rem!important}}@media (width <= 1200px){.container{padding:7rem 3rem 1rem!important}}\n"] }]
1513
+ }], ctorParameters: () => [{ type: ResourceService }, { type: i2.TagService }, { type: i2.AuthService }, { type: i0.Injector }], propDecorators: { showVaultSection: [{
1514
+ type: Input
1515
+ }], postSlice: [{
1516
+ type: Input
1517
+ }], categoryId: [{
1518
+ type: Input
1519
+ }], resourceTitle: [{
1520
+ type: Input
1521
+ }], tag: [{
1522
+ type: Input
1523
+ }] } });
1524
+
1525
+ class ResourceVideoCardComponent extends AppBaseComponent {
1526
+ constructor(sanitizer, resourceService, tagService, cdr, injector) {
1527
+ super(injector);
1528
+ this.sanitizer = sanitizer;
1529
+ this.resourceService = resourceService;
1530
+ this.tagService = tagService;
1531
+ this.cdr = cdr;
1532
+ this.showVideoSection = false;
1533
+ this.postSlice = false;
1534
+ this.canEditResourcesValue = false;
1535
+ this.masterSubscriptionId = this.appConfig.master_subscription.subscription_id;
1536
+ this.posts = [];
1537
+ this.isLoaded = false;
1538
+ this.videoStates = {};
1539
+ this.isEditingTitle = false;
1540
+ }
1541
+ ngOnInit() {
1542
+ if (this.userLoggedIn) {
1543
+ this.localStorage.getItem$('product').subscribe(res => {
1544
+ const data = res ? JSON.parse(res) : null;
1545
+ this.subscriptionId = data?.subscriptionId;
1546
+ });
1547
+ }
1548
+ this.getPosts(1, 10);
1549
+ }
1550
+ ngOnChanges(changes) {
1551
+ if (changes['user'] || changes['userLoggedIn']) {
1552
+ if (this.userLoggedIn && this.user) {
1553
+ this.updateCanEditResourcesValue();
1554
+ }
1555
+ }
1556
+ }
1557
+ loadVideo(post) {
1558
+ if (!post.external_url)
1559
+ return;
1560
+ const slug = post.slug;
1561
+ let externalUrl = post.external_url;
1562
+ // Append autoplay only when clicked
1563
+ externalUrl += externalUrl.includes('?') ? '&autoplay=1' : '?autoplay=1';
1564
+ // baseUrl is a trusted internal source (e.g. YouTube embed URL)
1565
+ this.videoStates[slug].url = this.sanitizer.bypassSecurityTrustResourceUrl(externalUrl); //NOSONAR
1566
+ }
1567
+ getPosts(page, pageSize) {
1568
+ this.isLoaded = false;
1569
+ this.resourceService
1570
+ .getPublicPosts(this.getEffectiveSubscriptionId(), page, pageSize, '', this.categoryId)
1571
+ .subscribe(response => {
1572
+ const sortedPosts = (response.posts ?? [])
1573
+ .filter(post => post.showcase === true)
1574
+ .sort((a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime());
1575
+ this.posts = this.postSlice ? sortedPosts : [...sortedPosts].slice(0, 3);
1576
+ this.posts.forEach(post => {
1577
+ if (post.external_url) {
1578
+ this.videoStates[post.slug] = {
1579
+ loaded: true,
1580
+ // baseUrl is a trusted internal source (e.g. YouTube embed URL)
1581
+ url: this.sanitizer.bypassSecurityTrustResourceUrl(post.external_url) //NOSONAR
1582
+ };
1583
+ }
1584
+ });
1585
+ })
1586
+ .add(() => {
1587
+ this.isLoaded = true;
1588
+ this.cdr.markForCheck();
1589
+ });
1590
+ }
1591
+ toggleTagEditTitle() {
1592
+ this.isEditingTitle = true;
1593
+ this.editedTitle = this.resourceTitle;
1594
+ }
1595
+ saveEditedTitle() {
1596
+ HelperService.updateTagTitle(this.tag, this.editedTitle, this.tagService, this.getEffectiveSubscriptionId(), this.toast).subscribe(() => {
1597
+ this.resourceTitle = this.editedTitle;
1598
+ this.isEditingTitle = false;
1599
+ this.cdr.markForCheck();
1600
+ });
1601
+ }
1602
+ /** Helper method to get effective subscription ID */
1603
+ getEffectiveSubscriptionId() {
1604
+ return HelperService.getEffectiveSubscriptionId(this.user, this.subscriptionId, this.masterSubscriptionId);
1605
+ }
1606
+ updateCanEditResourcesValue() {
1607
+ this.canEditResourcesValue = HelperService.canEditResources(this.user, this.userLoggedIn, this.permissionService);
1608
+ }
1609
+ canEditResources() {
1610
+ return this.canEditResourcesValue;
1611
+ }
1612
+ trackByPostId(index, post) {
1613
+ return post.id;
1614
+ }
1615
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceVideoCardComponent, deps: [{ token: i3$1.DomSanitizer }, { token: ResourceService }, { token: i2.TagService }, { token: i0.ChangeDetectorRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); }
1616
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: ResourceVideoCardComponent, selector: "pw-resource-video-card", inputs: { showVideoSection: "showVideoSection", categoryId: "categoryId", tag: "tag", postSlice: "postSlice", resourceTitle: "resourceTitle", user: "user", userLoggedIn: "userLoggedIn" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<section class=\"resource-vault-section bg-white text-center py-5 extra-top-padding section-outer\">\n <div class=\"container\">\n <div *ngIf=\"showVideoSection\" class=\"d-flex justify-content-between align-items-center flex-wrap\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"resourceTitle; else fallback\" [innerHTML]=\"resourceTitle\"></span>\n <ng-template #fallback>On-Demand Videos</ng-template>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleTagEditTitle()\" (keydown.enter)=\"toggleTagEditTitle()\" (keydown.space)=\"toggleTagEditTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle()\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n <a class=\"view-all\" routerLink=\"/resources/videos\">VIEW ALL ></a>\n </div>\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"posts.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n <div class=\"row mt-5 d-flex flex-wrap justify-content-center video-row\" *ngIf=\"posts.length !== 0 && isLoaded\">\n <div class=\"resource-blog-card\" *ngFor=\"let post of posts; trackBy: trackByPostId\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getPosts(1, 10)\">\n </pw-resource-edit-card-lazy>\n <p [innerHTML]=\"post.title\" class=\"mb-5\"></p>\n <a [href]=\" post.external_url\" target=\"_blank\">\n <img\n [src]=\"post.picture?.url\"\n class=\"img-fluid mb-3\"\n [alt]=\"post.title\"\n loading=\"lazy\" />\n </a>\n\n <a class=\"resource-btn mt-3\" [href]=\" post.external_url\" target=\"_blank\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Watch now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n </div>\n </div>\n </div>\n\n</section>\n", styles: [".bold{font-weight:700}.resource-heading{margin-bottom:2rem}.resource-note{margin-top:1rem;font-size:.85rem;color:#555}.resource-divider{border:0;height:40px;width:100%;background:linear-gradient(to bottom,#0000,#00000026);margin:0}.press-release-icon{height:auto!important;margin:0 11px 1.9rem;display:block;align-self:center;width:auto!important;aspect-ratio:0!important;object-fit:cover;margin-top:auto;margin-right:0!important}.resource-vault-section{padding:60px 0;background:#fff;padding-bottom:9rem!important;padding-top:7rem!important;box-shadow:0 4px 32px -14px #40576d4d!important}.resource-vault-section .vault-heading{font-size:3rem;font-weight:300}.resource-vault-section .explore-link{color:#000;font-weight:400;text-decoration:none;font-size:1.5rem}.resource-vault-section .resource-blog-card{display:flex;flex-direction:column;justify-content:space-between;background-color:#fff;border-radius:30px;box-shadow:0 20px 40px #00000014;padding:25px;text-align:center;width:338px;height:auto!important}.resource-vault-section .resource-blog-card h5{font-size:1.5rem;font-weight:400;margin-bottom:.5rem;color:var(--text-color, black)}.resource-vault-section .resource-blog-card p{font-size:1.5rem;color:var(--text-color, black);line-height:2rem}.resource-vault-section .resource-blog-card img{width:100%;border-radius:10px;aspect-ratio:1/1;object-fit:cover;margin-top:auto;margin-right:0!important;max-width:250px!important;align-self:center!important}.resource-vault-section .resource-blog-card iframe{height:210px;border-radius:10px;object-fit:cover;margin-right:0!important;max-width:280px!important}.resource-vault-section .resource-blog-card .resource-btn{background-color:var(--text-color, black);color:#fff;margin-top:auto;padding:10px 24px;border-radius:24px;font-size:1.5rem;font-weight:500;width:100%;max-width:240px;cursor:pointer;transition:background .3s ease;display:flex;justify-content:space-between;align-self:center;align-items:center;text-align:left;text-decoration:none;border:1px solid;box-shadow:none!important;border-color:var(--text-color, black)}.resource-vault-section .resource-blog-card .resource-btn:hover{background:#fff;color:var(--text-color, black)!important}.resource-vault-section .vault-description{text-align:left;max-width:657px;color:#182527;line-height:2.3rem!important;font-size:1.65rem}@media (width <= 1200px){.resource-vault-section .vault-heading{font-size:3.5rem}.resource-vault-section .vault-description{margin-top:1.35rem}.resource-vault-section .resource-btn{margin-left:0!important}}.video-row{gap:5.5rem!important;margin-top:3rem!important}@media (width >= 991px){section.bg-white.text-center.extra-top-padding{position:relative;overflow:hidden}section.bg-white.text-center.extra-top-padding .banner-header{margin-bottom:4rem!important}}.vault-header{text-align:left}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 768px){.video-row{gap:3rem!important}}@media (max-width: 768px){.resource-vault-section{padding-bottom:6rem!important}.resource-vault-section .container{padding-top:0rem!important;padding-bottom:0rem!important}.vault-header{text-align:center!important}.vault-heading{font-size:3rem!important}}@media (width <= 1200px){.container{padding:7rem 3rem 1rem!important}}\n"], dependencies: [{ kind: "directive", type: i3$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i6.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "component", type: i7.ProgressSpinner, selector: "p-progressSpinner", inputs: ["styleClass", "style", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i8.LazyImgDirective, selector: "img" }, { kind: "component", type: ResourceEditCardLazyComponent, selector: "pw-resource-edit-card-lazy", inputs: ["id", "resourceData", "canEdit"], outputs: ["updated"] }, { kind: "pipe", type: i10.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1617
+ }
1618
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceVideoCardComponent, decorators: [{
1619
+ type: Component,
1620
+ args: [{ selector: 'pw-resource-video-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section class=\"resource-vault-section bg-white text-center py-5 extra-top-padding section-outer\">\n <div class=\"container\">\n <div *ngIf=\"showVideoSection\" class=\"d-flex justify-content-between align-items-center flex-wrap\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"resourceTitle; else fallback\" [innerHTML]=\"resourceTitle\"></span>\n <ng-template #fallback>On-Demand Videos</ng-template>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleTagEditTitle()\" (keydown.enter)=\"toggleTagEditTitle()\" (keydown.space)=\"toggleTagEditTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle()\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n <a class=\"view-all\" routerLink=\"/resources/videos\">VIEW ALL ></a>\n </div>\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"posts.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n <div class=\"row mt-5 d-flex flex-wrap justify-content-center video-row\" *ngIf=\"posts.length !== 0 && isLoaded\">\n <div class=\"resource-blog-card\" *ngFor=\"let post of posts; trackBy: trackByPostId\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getPosts(1, 10)\">\n </pw-resource-edit-card-lazy>\n <p [innerHTML]=\"post.title\" class=\"mb-5\"></p>\n <a [href]=\" post.external_url\" target=\"_blank\">\n <img\n [src]=\"post.picture?.url\"\n class=\"img-fluid mb-3\"\n [alt]=\"post.title\"\n loading=\"lazy\" />\n </a>\n\n <a class=\"resource-btn mt-3\" [href]=\" post.external_url\" target=\"_blank\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Watch now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n </div>\n </div>\n </div>\n\n</section>\n", styles: [".bold{font-weight:700}.resource-heading{margin-bottom:2rem}.resource-note{margin-top:1rem;font-size:.85rem;color:#555}.resource-divider{border:0;height:40px;width:100%;background:linear-gradient(to bottom,#0000,#00000026);margin:0}.press-release-icon{height:auto!important;margin:0 11px 1.9rem;display:block;align-self:center;width:auto!important;aspect-ratio:0!important;object-fit:cover;margin-top:auto;margin-right:0!important}.resource-vault-section{padding:60px 0;background:#fff;padding-bottom:9rem!important;padding-top:7rem!important;box-shadow:0 4px 32px -14px #40576d4d!important}.resource-vault-section .vault-heading{font-size:3rem;font-weight:300}.resource-vault-section .explore-link{color:#000;font-weight:400;text-decoration:none;font-size:1.5rem}.resource-vault-section .resource-blog-card{display:flex;flex-direction:column;justify-content:space-between;background-color:#fff;border-radius:30px;box-shadow:0 20px 40px #00000014;padding:25px;text-align:center;width:338px;height:auto!important}.resource-vault-section .resource-blog-card h5{font-size:1.5rem;font-weight:400;margin-bottom:.5rem;color:var(--text-color, black)}.resource-vault-section .resource-blog-card p{font-size:1.5rem;color:var(--text-color, black);line-height:2rem}.resource-vault-section .resource-blog-card img{width:100%;border-radius:10px;aspect-ratio:1/1;object-fit:cover;margin-top:auto;margin-right:0!important;max-width:250px!important;align-self:center!important}.resource-vault-section .resource-blog-card iframe{height:210px;border-radius:10px;object-fit:cover;margin-right:0!important;max-width:280px!important}.resource-vault-section .resource-blog-card .resource-btn{background-color:var(--text-color, black);color:#fff;margin-top:auto;padding:10px 24px;border-radius:24px;font-size:1.5rem;font-weight:500;width:100%;max-width:240px;cursor:pointer;transition:background .3s ease;display:flex;justify-content:space-between;align-self:center;align-items:center;text-align:left;text-decoration:none;border:1px solid;box-shadow:none!important;border-color:var(--text-color, black)}.resource-vault-section .resource-blog-card .resource-btn:hover{background:#fff;color:var(--text-color, black)!important}.resource-vault-section .vault-description{text-align:left;max-width:657px;color:#182527;line-height:2.3rem!important;font-size:1.65rem}@media (width <= 1200px){.resource-vault-section .vault-heading{font-size:3.5rem}.resource-vault-section .vault-description{margin-top:1.35rem}.resource-vault-section .resource-btn{margin-left:0!important}}.video-row{gap:5.5rem!important;margin-top:3rem!important}@media (width >= 991px){section.bg-white.text-center.extra-top-padding{position:relative;overflow:hidden}section.bg-white.text-center.extra-top-padding .banner-header{margin-bottom:4rem!important}}.vault-header{text-align:left}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 768px){.video-row{gap:3rem!important}}@media (max-width: 768px){.resource-vault-section{padding-bottom:6rem!important}.resource-vault-section .container{padding-top:0rem!important;padding-bottom:0rem!important}.vault-header{text-align:center!important}.vault-heading{font-size:3rem!important}}@media (width <= 1200px){.container{padding:7rem 3rem 1rem!important}}\n"] }]
1621
+ }], ctorParameters: () => [{ type: i3$1.DomSanitizer }, { type: ResourceService }, { type: i2.TagService }, { type: i0.ChangeDetectorRef }, { type: i0.Injector }], propDecorators: { showVideoSection: [{
1622
+ type: Input
1623
+ }], categoryId: [{
1624
+ type: Input
1625
+ }], tag: [{
1626
+ type: Input
1627
+ }], postSlice: [{
1628
+ type: Input
1629
+ }], resourceTitle: [{
1630
+ type: Input
1631
+ }], user: [{
1632
+ type: Input
1633
+ }], userLoggedIn: [{
1634
+ type: Input
1635
+ }] } });
1636
+
1637
+ class UpcomingEventCardComponent extends AppBaseComponent {
1638
+ constructor(resourceService, tagService, cdr, injector) {
1639
+ super(injector);
1640
+ this.resourceService = resourceService;
1641
+ this.tagService = tagService;
1642
+ this.cdr = cdr;
1643
+ this.showEventContent = false;
1644
+ this.postSlice = false;
1645
+ this.canEditResourcesValue = false;
1646
+ this.now = new Date().getTime();
1647
+ this.isEditingTitle = false;
1648
+ this.masterSubscriptionId = this.appConfig.master_subscription.subscription_id;
1649
+ this.posts = [];
1650
+ this.isLoaded = false;
1651
+ }
1652
+ ngOnInit() {
1653
+ if (this.userLoggedIn) {
1654
+ this.localStorage.getItem$('product').subscribe(res => {
1655
+ const data = res ? JSON.parse(res) : null;
1656
+ this.subscriptionId = data?.subscriptionId;
1657
+ });
1658
+ this.getPostTags();
1659
+ }
1660
+ else {
1661
+ this.getPostTags();
1662
+ }
1663
+ }
1664
+ ngOnChanges(changes) {
1665
+ if (changes['user'] || changes['userLoggedIn']) {
1666
+ if (this.userLoggedIn && this.user) {
1667
+ this.updateCanEditResourcesValue();
1668
+ }
1669
+ }
1670
+ }
1671
+ getPostTags() {
1672
+ this.tagService
1673
+ .getTagsByType('post_categories', {}, this.getEffectiveSubscriptionId())
1674
+ .subscribe(response => {
1675
+ this.blogPostTag = response.tags.find(tag => tag.name === 'Events');
1676
+ if (this.blogPostTag?.tag_category_id) {
1677
+ if (this.postSlice) {
1678
+ this.getPosts(1, 100);
1679
+ }
1680
+ else {
1681
+ this.getAllPosts(1, 100);
1682
+ }
1683
+ }
1684
+ else {
1685
+ this.isLoaded = true;
1686
+ this.cdr.markForCheck();
1687
+ }
1688
+ });
1689
+ }
1690
+ getPosts(page, pageSize) {
1691
+ this.isLoaded = false;
1692
+ this.resourceService
1693
+ .getPublicPosts(this.getEffectiveSubscriptionId(), page, pageSize, '', this.categoryId ?? this.blogPostTag?.tag_category_id)
1694
+ .subscribe(response => {
1695
+ const sortedPosts = (response.posts ?? [])
1696
+ .filter(post => post.showcase === true && new Date(post?.when).getTime() > this.now)
1697
+ .sort((a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime());
1698
+ this.posts = sortedPosts;
1699
+ })
1700
+ .add(() => {
1701
+ this.isLoaded = true;
1702
+ this.cdr.markForCheck();
1703
+ });
1704
+ }
1705
+ isUpcoming(post) {
1706
+ return new Date(post?.when).getTime() > this.now;
1707
+ }
1708
+ getAllPosts(page, pageSize) {
1709
+ this.isLoaded = false;
1710
+ this.resourceService
1711
+ .getPublicPosts(this.getEffectiveSubscriptionId(), page, pageSize, '', this.categoryId ?? this.blogPostTag?.tag_category_id)
1712
+ .subscribe(response => {
1713
+ const sortedPosts = (response.posts ?? [])
1714
+ .filter(post => post.showcase === true)
1715
+ .sort((a, b) => new Date(b.when).getTime() - new Date(a.when).getTime());
1716
+ this.posts = [...sortedPosts].slice(0, 3).reverse();
1717
+ })
1718
+ .add(() => {
1719
+ this.isLoaded = true;
1720
+ this.cdr.markForCheck();
1721
+ });
1722
+ }
1723
+ toggleEditTitle() {
1724
+ this.isEditingTitle = true;
1725
+ this.editedTitle = this.resourceTitle;
1726
+ }
1727
+ saveEditedTitle() {
1728
+ HelperService.updateTagTitle(this.tag, this.editedTitle, this.tagService, this.getEffectiveSubscriptionId(), this.toast).subscribe(() => {
1729
+ this.resourceTitle = this.editedTitle;
1730
+ this.isEditingTitle = false;
1731
+ this.cdr.markForCheck();
1732
+ });
1733
+ }
1734
+ /** Helper method to get effective subscription ID */
1735
+ getEffectiveSubscriptionId() {
1736
+ return HelperService.getEffectiveSubscriptionId(this.user, this.subscriptionId, this.masterSubscriptionId);
1737
+ }
1738
+ updateCanEditResourcesValue() {
1739
+ this.canEditResourcesValue = HelperService.canEditResources(this.user, this.userLoggedIn, this.permissionService);
1740
+ }
1741
+ canEditResources() {
1742
+ return this.canEditResourcesValue;
1743
+ }
1744
+ trackByPostId(index, post) {
1745
+ return post.id;
1746
+ }
1747
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: UpcomingEventCardComponent, deps: [{ token: ResourceService }, { token: i2.TagService }, { token: i0.ChangeDetectorRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); }
1748
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: UpcomingEventCardComponent, selector: "pw-upcoming-event-card", inputs: { showEventContent: "showEventContent", categoryId: "categoryId", tag: "tag", postSlice: "postSlice", resourceTitle: "resourceTitle", user: "user", userLoggedIn: "userLoggedIn" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<section class=\"resource-vault-section bg-white text-center py-5 extra-top-padding section-outer\">\n <div class=\"container\">\n <div *ngIf=\"showEventContent\" class=\"d-flex justify-content-between align-items-center flex-wrap\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"resourceTitle; else fallback\" [innerHTML]=\"resourceTitle\"></span>\n <ng-template #fallback>Events &amp; Webinars</ng-template>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleEditTitle()\" (keydown.enter)=\"toggleEditTitle()\" (keydown.space)=\"toggleEditTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle()\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n <a class=\"view-all\" routerLink=\"/resources/events\">VIEW ALL ></a>\n </div>\n <div *ngIf=\"!showEventContent\" class=\"d-md-flex justify-content-between align-items-start\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"resourceTitle; else fallback\" [innerHTML]=\"resourceTitle\"></span>\n <ng-template #fallback>Upcoming Events</ng-template>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleEditTitle()\" (keydown.enter)=\"toggleEditTitle()\" (keydown.space)=\"toggleEditTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle()\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n </div>\n\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"posts.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n\n <div class=\"row mt-5 d-flex flex-wrap justify-content-center gap-4 video-row\" *ngIf=\"posts.length !== 0 && isLoaded\">\n <div class=\"resource-blog-card d text-center p-4\" *ngFor=\"let post of posts; trackBy: trackByPostId\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getAllPosts(1, 100)\">\n </pw-resource-edit-card-lazy>\n <ng-container *ngIf=\"postSlice; else conditionalCheck\">\n <h5 class=\"badge-title fw-bold\">UPCOMING:</h5>\n </ng-container>\n\n <ng-template #conditionalCheck>\n <h5 class=\"badge-title fw-bold\">\n {{ isUpcoming(post) ? 'UPCOMING:' : 'REPLAY:' }}\n </h5>\n </ng-template>\n\n <p class=\"event-title mb-4\" [innerHtml]=\"post?.title\"></p>\n <a\n [href]=\"post.external_url || ('/resources/view/' + post?.slug)\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Navigate to resource\"\n >\n <img\n [src]=\"post.picture.url\"\n class=\"img-fluid my-3 mt-auto\"\n alt=\"Webinar\"\n loading=\"lazy\"\n />\n </a>\n\n <a *ngIf=\"post?.external_url; else internalLink\"\n class=\"resource-btn mt-3\"\n aria-label=\"Navigate to external url\"\n [href]=\"post.external_url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n\n <ng-template #internalLink>\n <a class=\"resource-btn mt-3\" aria-label=\"Navigate to resource view\" [href]=\"'/resources/view/' + post?.slug\" target=\"_blank\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n </ng-template>\n </div>\n </div>\n </div>\n</section>\n\n\n<section class=\"bg-white\" *ngIf=\"!showEventContent\">\n <pw-replay-event-card [resourceTitle]=\"resourceTitle\" [user]=\"user\" [userLoggedIn]=\"userLoggedIn\"></pw-replay-event-card>\n</section>", styles: [".bold{font-weight:700}.resource-heading{margin-bottom:2rem}.resource-note{margin-top:1rem;font-size:.85rem;color:#555}.resource-divider{border:0;height:40px;width:100%;background:linear-gradient(to bottom,#0000,#00000026);margin:0}.press-release-icon{height:auto!important;margin:0 11px 1.9rem;display:block;align-self:center;width:auto!important;aspect-ratio:0!important;object-fit:cover;margin-top:auto;margin-right:0!important}.resource-vault-section{padding:60px 0;background:#fff;padding-bottom:9rem!important;padding-top:7rem!important;box-shadow:0 4px 32px -14px #40576d4d!important}.resource-vault-section .vault-heading{font-size:3rem;font-weight:300}.resource-vault-section .explore-link{color:#000;font-weight:400;text-decoration:none;font-size:1.5rem}.resource-vault-section .resource-blog-card{display:flex;flex-direction:column;justify-content:space-between;background-color:#fff;border-radius:30px;box-shadow:0 20px 40px #00000014;padding:25px;text-align:center;width:338px;height:auto!important}.resource-vault-section .resource-blog-card h5{font-size:1.5rem;font-weight:400;margin-bottom:.5rem;color:var(--text-color, black)}.resource-vault-section .resource-blog-card p{font-size:1.5rem;color:var(--text-color, black);line-height:2rem}.resource-vault-section .resource-blog-card img{width:100%;border-radius:10px;aspect-ratio:1/1;object-fit:cover;margin-top:auto;margin-right:0!important;max-width:250px!important;align-self:center!important}.resource-vault-section .resource-blog-card iframe{height:210px;border-radius:10px;object-fit:cover;margin-right:0!important;max-width:280px!important}.resource-vault-section .resource-blog-card .resource-btn{background-color:var(--text-color, black);color:#fff;margin-top:auto;padding:10px 24px;border-radius:24px;font-size:1.5rem;font-weight:500;width:100%;max-width:240px;cursor:pointer;transition:background .3s ease;display:flex;justify-content:space-between;align-self:center;align-items:center;text-align:left;text-decoration:none;border:1px solid;box-shadow:none!important;border-color:var(--text-color, black)}.resource-vault-section .resource-blog-card .resource-btn:hover{background:#fff;color:var(--text-color, black)!important}.resource-vault-section .vault-description{text-align:left;max-width:657px;color:#182527;line-height:2.3rem!important;font-size:1.65rem}@media (width <= 1200px){.resource-vault-section .vault-heading{font-size:3.5rem}.resource-vault-section .vault-description{margin-top:1.35rem}.resource-vault-section .resource-btn{margin-left:0!important}}.video-row{gap:5.5rem!important;margin-top:3rem!important}@media (width >= 991px){section.bg-white.text-center.extra-top-padding{position:relative;overflow:hidden}section.bg-white.text-center.extra-top-padding .banner-header{margin-bottom:4rem!important}}.vault-header{text-align:left}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 768px){.video-row{gap:3rem!important}}@media (max-width: 768px){.resource-vault-section{padding-bottom:6rem!important}.resource-vault-section .container{padding-top:0rem!important;padding-bottom:0rem!important}.vault-header{text-align:center!important}.vault-heading{font-size:3rem!important}}@media (width <= 1200px){.container{padding:7rem 3rem 1rem!important}}\n"], dependencies: [{ kind: "directive", type: i3$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i6.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "component", type: i7.ProgressSpinner, selector: "p-progressSpinner", inputs: ["styleClass", "style", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i8.LazyImgDirective, selector: "img" }, { kind: "component", type: ResourceEditCardLazyComponent, selector: "pw-resource-edit-card-lazy", inputs: ["id", "resourceData", "canEdit"], outputs: ["updated"] }, { kind: "pipe", type: i10.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1749
+ }
1750
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: UpcomingEventCardComponent, decorators: [{
1751
+ type: Component,
1752
+ args: [{ selector: 'pw-upcoming-event-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section class=\"resource-vault-section bg-white text-center py-5 extra-top-padding section-outer\">\n <div class=\"container\">\n <div *ngIf=\"showEventContent\" class=\"d-flex justify-content-between align-items-center flex-wrap\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"resourceTitle; else fallback\" [innerHTML]=\"resourceTitle\"></span>\n <ng-template #fallback>Events &amp; Webinars</ng-template>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleEditTitle()\" (keydown.enter)=\"toggleEditTitle()\" (keydown.space)=\"toggleEditTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle()\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n <a class=\"view-all\" routerLink=\"/resources/events\">VIEW ALL ></a>\n </div>\n <div *ngIf=\"!showEventContent\" class=\"d-md-flex justify-content-between align-items-start\">\n <h2 class=\"section-heading d-flex align-items-center\" [ngClass]=\"{ 'w-50': isEditingTitle }\">\n <ng-container *ngIf=\"!isEditingTitle; else editTitleBlock\">\n <span *ngIf=\"resourceTitle; else fallback\" [innerHTML]=\"resourceTitle\"></span>\n <ng-template #fallback>Upcoming Events</ng-template>\n <i *ngIf=\"canEditResourcesValue\" class=\"fa fa-edit in-page-edit-icon ms-3 cursor-pointer\" (click)=\"toggleEditTitle()\" (keydown.enter)=\"toggleEditTitle()\" (keydown.space)=\"toggleEditTitle()\" title=\"Edit Title\"></i>\n </ng-container>\n\n <ng-template #editTitleBlock>\n <input [(ngModel)]=\"editedTitle\" class=\"form-control d-inline w-auto me-2\" [ngClass]=\"{ 'w-100': isEditingTitle }\" />\n <button class=\"btn btn-sm btn-primary me-1\" (click)=\"saveEditedTitle()\">Save</button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"isEditingTitle = false\">Cancel</button>\n </ng-template>\n </h2>\n </div>\n\n <div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <div *ngIf=\"posts.length === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n\n <div class=\"row mt-5 d-flex flex-wrap justify-content-center gap-4 video-row\" *ngIf=\"posts.length !== 0 && isLoaded\">\n <div class=\"resource-blog-card d text-center p-4\" *ngFor=\"let post of posts; trackBy: trackByPostId\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEditResourcesValue\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"getAllPosts(1, 100)\">\n </pw-resource-edit-card-lazy>\n <ng-container *ngIf=\"postSlice; else conditionalCheck\">\n <h5 class=\"badge-title fw-bold\">UPCOMING:</h5>\n </ng-container>\n\n <ng-template #conditionalCheck>\n <h5 class=\"badge-title fw-bold\">\n {{ isUpcoming(post) ? 'UPCOMING:' : 'REPLAY:' }}\n </h5>\n </ng-template>\n\n <p class=\"event-title mb-4\" [innerHtml]=\"post?.title\"></p>\n <a\n [href]=\"post.external_url || ('/resources/view/' + post?.slug)\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Navigate to resource\"\n >\n <img\n [src]=\"post.picture.url\"\n class=\"img-fluid my-3 mt-auto\"\n alt=\"Webinar\"\n loading=\"lazy\"\n />\n </a>\n\n <a *ngIf=\"post?.external_url; else internalLink\"\n class=\"resource-btn mt-3\"\n aria-label=\"Navigate to external url\"\n [href]=\"post.external_url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n\n <ng-template #internalLink>\n <a class=\"resource-btn mt-3\" aria-label=\"Navigate to resource view\" [href]=\"'/resources/view/' + post?.slug\" target=\"_blank\">\n <span>{{ post?.cta_text && post.cta_text !== 'null' ? post.cta_text : 'Read Now' }}</span>\n <span class=\"arrow\">\u2192</span>\n </a>\n </ng-template>\n </div>\n </div>\n </div>\n</section>\n\n\n<section class=\"bg-white\" *ngIf=\"!showEventContent\">\n <pw-replay-event-card [resourceTitle]=\"resourceTitle\" [user]=\"user\" [userLoggedIn]=\"userLoggedIn\"></pw-replay-event-card>\n</section>", styles: [".bold{font-weight:700}.resource-heading{margin-bottom:2rem}.resource-note{margin-top:1rem;font-size:.85rem;color:#555}.resource-divider{border:0;height:40px;width:100%;background:linear-gradient(to bottom,#0000,#00000026);margin:0}.press-release-icon{height:auto!important;margin:0 11px 1.9rem;display:block;align-self:center;width:auto!important;aspect-ratio:0!important;object-fit:cover;margin-top:auto;margin-right:0!important}.resource-vault-section{padding:60px 0;background:#fff;padding-bottom:9rem!important;padding-top:7rem!important;box-shadow:0 4px 32px -14px #40576d4d!important}.resource-vault-section .vault-heading{font-size:3rem;font-weight:300}.resource-vault-section .explore-link{color:#000;font-weight:400;text-decoration:none;font-size:1.5rem}.resource-vault-section .resource-blog-card{display:flex;flex-direction:column;justify-content:space-between;background-color:#fff;border-radius:30px;box-shadow:0 20px 40px #00000014;padding:25px;text-align:center;width:338px;height:auto!important}.resource-vault-section .resource-blog-card h5{font-size:1.5rem;font-weight:400;margin-bottom:.5rem;color:var(--text-color, black)}.resource-vault-section .resource-blog-card p{font-size:1.5rem;color:var(--text-color, black);line-height:2rem}.resource-vault-section .resource-blog-card img{width:100%;border-radius:10px;aspect-ratio:1/1;object-fit:cover;margin-top:auto;margin-right:0!important;max-width:250px!important;align-self:center!important}.resource-vault-section .resource-blog-card iframe{height:210px;border-radius:10px;object-fit:cover;margin-right:0!important;max-width:280px!important}.resource-vault-section .resource-blog-card .resource-btn{background-color:var(--text-color, black);color:#fff;margin-top:auto;padding:10px 24px;border-radius:24px;font-size:1.5rem;font-weight:500;width:100%;max-width:240px;cursor:pointer;transition:background .3s ease;display:flex;justify-content:space-between;align-self:center;align-items:center;text-align:left;text-decoration:none;border:1px solid;box-shadow:none!important;border-color:var(--text-color, black)}.resource-vault-section .resource-blog-card .resource-btn:hover{background:#fff;color:var(--text-color, black)!important}.resource-vault-section .vault-description{text-align:left;max-width:657px;color:#182527;line-height:2.3rem!important;font-size:1.65rem}@media (width <= 1200px){.resource-vault-section .vault-heading{font-size:3.5rem}.resource-vault-section .vault-description{margin-top:1.35rem}.resource-vault-section .resource-btn{margin-left:0!important}}.video-row{gap:5.5rem!important;margin-top:3rem!important}@media (width >= 991px){section.bg-white.text-center.extra-top-padding{position:relative;overflow:hidden}section.bg-white.text-center.extra-top-padding .banner-header{margin-bottom:4rem!important}}.vault-header{text-align:left}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 768px){.video-row{gap:3rem!important}}@media (max-width: 768px){.resource-vault-section{padding-bottom:6rem!important}.resource-vault-section .container{padding-top:0rem!important;padding-bottom:0rem!important}.vault-header{text-align:center!important}.vault-heading{font-size:3rem!important}}@media (width <= 1200px){.container{padding:7rem 3rem 1rem!important}}\n"] }]
1753
+ }], ctorParameters: () => [{ type: ResourceService }, { type: i2.TagService }, { type: i0.ChangeDetectorRef }, { type: i0.Injector }], propDecorators: { showEventContent: [{
1754
+ type: Input
1755
+ }], categoryId: [{
1756
+ type: Input
1757
+ }], tag: [{
1758
+ type: Input
1759
+ }], postSlice: [{
1760
+ type: Input
1761
+ }], resourceTitle: [{
1762
+ type: Input
1763
+ }], user: [{
1764
+ type: Input
1765
+ }], userLoggedIn: [{
1766
+ type: Input
1767
+ }] } });
1768
+
1769
+ /**
1770
+ * Module containing resource card components (lightweight version)
1771
+ * ResourceEditCard is lazy-loaded on demand to save 145 KB
1772
+ * Trial4ContactUs moved to separate module for better tree-shaking
1773
+ * Used by both ResourceRootModule and ResourceSharedModule
1774
+ */
1775
+ class ResourceCardsModule {
1776
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceCardsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1777
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.11", ngImport: i0, type: ResourceCardsModule, declarations: [ResourceVideoCardComponent,
1778
+ UpcomingEventCardComponent,
1779
+ ResourceCardComponent,
1780
+ CaseStudyCardComponent,
1781
+ ResourceNoteCardComponent,
1782
+ ResourceVaultComponent,
1783
+ ResourceEditCardLazyComponent], imports: [CommonModule,
1784
+ RouterModule,
1785
+ FormsModule,
1786
+ ReactiveFormsModule,
1787
+ PipesModule,
1788
+ PaginatorModule,
1789
+ DropdownModule,
1790
+ ResourceSharedComponentsModule,
1791
+ CoreTranslocoModule,
1792
+ TranslocoModule,
1793
+ DirectivesModule,
1794
+ DragDropModule,
1795
+ NgxCaptchaModule,
1796
+ Trial4ContactUsModule // ✅ Import standalone module
1797
+ ], exports: [ResourceVideoCardComponent,
1798
+ UpcomingEventCardComponent,
1799
+ ResourceCardComponent,
1800
+ CaseStudyCardComponent,
1801
+ ResourceNoteCardComponent,
1802
+ ResourceVaultComponent,
1803
+ Trial4ContactUsModule, // ✅ Re-export for backward compatibility
1804
+ ResourceEditCardLazyComponent] }); }
1805
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceCardsModule, imports: [CommonModule,
1806
+ RouterModule,
1807
+ FormsModule,
1808
+ ReactiveFormsModule,
1809
+ PipesModule,
1810
+ PaginatorModule,
1811
+ DropdownModule,
1812
+ ResourceSharedComponentsModule,
1813
+ CoreTranslocoModule,
1814
+ TranslocoModule,
1815
+ DirectivesModule,
1816
+ DragDropModule,
1817
+ NgxCaptchaModule,
1818
+ Trial4ContactUsModule // ✅ Import standalone module
1819
+ , Trial4ContactUsModule] }); }
1820
+ }
1821
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceCardsModule, decorators: [{
1822
+ type: NgModule,
1823
+ args: [{
1824
+ declarations: [
1825
+ ResourceVideoCardComponent,
1826
+ UpcomingEventCardComponent,
1827
+ ResourceCardComponent,
1828
+ CaseStudyCardComponent,
1829
+ ResourceNoteCardComponent,
1830
+ ResourceVaultComponent,
1831
+ ResourceEditCardLazyComponent
1832
+ ],
1833
+ imports: [
1834
+ CommonModule,
1835
+ RouterModule,
1836
+ FormsModule,
1837
+ ReactiveFormsModule,
1838
+ PipesModule,
1839
+ PaginatorModule,
1840
+ DropdownModule,
1841
+ ResourceSharedComponentsModule,
1842
+ CoreTranslocoModule,
1843
+ TranslocoModule,
1844
+ DirectivesModule,
1845
+ DragDropModule,
1846
+ NgxCaptchaModule,
1847
+ Trial4ContactUsModule // ✅ Import standalone module
1848
+ ],
1849
+ exports: [
1850
+ ResourceVideoCardComponent,
1851
+ UpcomingEventCardComponent,
1852
+ ResourceCardComponent,
1853
+ CaseStudyCardComponent,
1854
+ ResourceNoteCardComponent,
1855
+ ResourceVaultComponent,
1856
+ Trial4ContactUsModule, // ✅ Re-export for backward compatibility
1857
+ ResourceEditCardLazyComponent
1858
+ ],
1859
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
1860
+ }]
1861
+ }] });
1862
+
1863
+ // Shared components used across multiple resource routes
1864
+ // Note: Most heavy modules (Quill, Calendar, UiSwitch, etc.) are now in ResourceCardsModule
1865
+ class ResourceSharedModule {
1866
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceSharedModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1867
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.11", ngImport: i0, type: ResourceSharedModule, declarations: [ResourceCompanyCardComponent, ResourceTopBannerEditComponent], imports: [CommonModule,
1868
+ RouterModule,
1869
+ FormsModule,
1870
+ ReactiveFormsModule,
1871
+ PipesModule,
1872
+ ResourceSharedComponentsModule,
1873
+ CoreTranslocoModule,
1874
+ TranslocoModule,
1875
+ DirectivesModule,
1876
+ InputTextModule,
1877
+ InputTextareaModule,
1878
+ ResourceCardsModule], exports: [
1879
+ // Export the 2 components specific to this module
1880
+ ResourceCompanyCardComponent,
1881
+ ResourceTopBannerEditComponent,
1882
+ // Export card components module (includes all heavy modules + card components)
1883
+ ResourceCardsModule,
1884
+ // Export common lightweight modules
1885
+ CommonModule,
1886
+ RouterModule,
1887
+ FormsModule,
1888
+ ReactiveFormsModule,
1889
+ PipesModule,
1890
+ ResourceSharedComponentsModule,
1891
+ CoreTranslocoModule,
1892
+ TranslocoModule,
1893
+ DirectivesModule,
1894
+ InputTextModule,
1895
+ InputTextareaModule] }); }
1896
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceSharedModule, imports: [CommonModule,
1897
+ RouterModule,
1898
+ FormsModule,
1899
+ ReactiveFormsModule,
1900
+ PipesModule,
1901
+ ResourceSharedComponentsModule,
1902
+ CoreTranslocoModule,
1903
+ TranslocoModule,
1904
+ DirectivesModule,
1905
+ InputTextModule,
1906
+ InputTextareaModule,
1907
+ ResourceCardsModule,
1908
+ // Export card components module (includes all heavy modules + card components)
1909
+ ResourceCardsModule,
1910
+ // Export common lightweight modules
1911
+ CommonModule,
1912
+ RouterModule,
1913
+ FormsModule,
1914
+ ReactiveFormsModule,
1915
+ PipesModule,
1916
+ ResourceSharedComponentsModule,
1917
+ CoreTranslocoModule,
1918
+ TranslocoModule,
1919
+ DirectivesModule,
1920
+ InputTextModule,
1921
+ InputTextareaModule] }); }
1922
+ }
1923
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceSharedModule, decorators: [{
1924
+ type: NgModule,
1925
+ args: [{
1926
+ declarations: [ResourceCompanyCardComponent, ResourceTopBannerEditComponent],
1927
+ imports: [
1928
+ CommonModule,
1929
+ RouterModule,
1930
+ FormsModule,
1931
+ ReactiveFormsModule,
1932
+ PipesModule,
1933
+ ResourceSharedComponentsModule,
1934
+ CoreTranslocoModule,
1935
+ TranslocoModule,
1936
+ DirectivesModule,
1937
+ InputTextModule,
1938
+ InputTextareaModule,
1939
+ ResourceCardsModule
1940
+ ],
1941
+ exports: [
1942
+ // Export the 2 components specific to this module
1943
+ ResourceCompanyCardComponent,
1944
+ ResourceTopBannerEditComponent,
1945
+ // Export card components module (includes all heavy modules + card components)
1946
+ ResourceCardsModule,
1947
+ // Export common lightweight modules
1948
+ CommonModule,
1949
+ RouterModule,
1950
+ FormsModule,
1951
+ ReactiveFormsModule,
1952
+ PipesModule,
1953
+ ResourceSharedComponentsModule,
1954
+ CoreTranslocoModule,
1955
+ TranslocoModule,
1956
+ DirectivesModule,
1957
+ InputTextModule,
1958
+ InputTextareaModule
1959
+ ],
1960
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
1961
+ }]
1962
+ }] });
1963
+
1964
+ class ResourceEditCardComponent extends AppBaseComponent {
1965
+ constructor(fb, modalService, resourceService, authService, tagService, injector) {
1966
+ super(injector);
1967
+ this.fb = fb;
1968
+ this.modalService = modalService;
1969
+ this.resourceService = resourceService;
1970
+ this.authService = authService;
1971
+ this.tagService = tagService;
1972
+ this.updated = new EventEmitter();
1973
+ this.image = '';
1974
+ this.rectangularImage = '';
1975
+ this.file = null;
1976
+ this.rectangularFile = null;
1977
+ this.selectedTags = [];
1978
+ this.allTags = [];
1979
+ this.tagsSuggestion = [];
1980
+ this.buttonBusy = false;
1981
+ this.editForm = this.fb.group({
1982
+ title: [''],
1983
+ external_url: [''],
1984
+ cta_text: [''],
1985
+ when: [''],
1986
+ showcase: [false],
1987
+ published_at: [false],
1988
+ accepted_at: [false],
1989
+ body: ['']
1990
+ });
1991
+ }
1992
+ ngOnInit() {
1993
+ this.authService.getToken$().subscribe(res => {
1994
+ this.userLoggedIn = !!res;
1995
+ if (this.userLoggedIn) {
1996
+ this.localStorage.getItem$('product').subscribe(res => {
1997
+ const data = res ? JSON.parse(res) : null;
1998
+ this.subscriptionId = data?.subscriptionId;
1999
+ });
2000
+ }
2001
+ });
2002
+ }
2003
+ navigateToResourceEdit() {
2004
+ const basePath = `/admin/resources/${this.resourceData?.slug}`;
2005
+ const fullUrl = `${location.origin}${basePath}`;
2006
+ window.open(fullUrl, '_blank');
2007
+ }
2008
+ openModal(modalTemplate) {
2009
+ if (this.resourceData) {
2010
+ const when = this.resourceData.when ? new Date(this.resourceData.when) : null;
2011
+ this.editForm.setValue({
2012
+ title: this.resourceData.title ?? '',
2013
+ external_url: this.resourceData.external_url ?? '',
2014
+ cta_text: this.resourceData.cta_text ?? '',
2015
+ when: when ?? '',
2016
+ showcase: !!this.resourceData.showcase,
2017
+ published_at: !!this.resourceData.published_at,
2018
+ accepted_at: !!this.resourceData.accepted_at,
2019
+ body: this.resourceData.body
2020
+ });
2021
+ this.image = this.resourceData.picture?.url ?? '';
2022
+ this.selectedTags = this.resourceData?.tags?.length ? [...this.resourceData.tags] : [];
2023
+ this.rectangularImage = this.resourceData.rectangular_picture?.url ?? '';
2024
+ }
2025
+ this.modalService.open(modalTemplate, { centered: true, size: 'lg' });
2026
+ this.getPostTags();
2027
+ }
2028
+ search(event) {
2029
+ let values = [];
2030
+ if (event.query) {
2031
+ values = this.allTags.filter(x => x.name.toLowerCase().includes(event.query.toLowerCase()));
2032
+ }
2033
+ else {
2034
+ this.allTags.forEach(element => {
2035
+ values.push(element);
2036
+ });
2037
+ }
2038
+ this.tagsSuggestion = values;
2039
+ }
2040
+ getPostTags() {
2041
+ this.tagService
2042
+ .getTagsByType('post_categories', {}, this.subscriptionId)
2043
+ .subscribe(response => {
2044
+ this.allTags = response.tags;
2045
+ });
2046
+ }
2047
+ deleteRectangularImage() {
2048
+ this.rectangularImage = null;
2049
+ this.rectangularFile = null;
2050
+ }
2051
+ openImageModal(modalTemplate) {
2052
+ this.imageModalRef = this.modalService.open(modalTemplate, { centered: true, size: 'md' });
2053
+ }
2054
+ onImageSelected(base64) {
2055
+ this.image = base64;
2056
+ this.file = HelperService.convertBase64ToFile(base64);
2057
+ this.imageModalRef?.close();
2058
+ }
2059
+ onRectangularImageSelection(base64) {
2060
+ this.rectangularImage = base64;
2061
+ this.rectangularFile = HelperService.convertBase64ToFile(base64);
2062
+ this.imageModalRef?.close();
2063
+ }
2064
+ removeImage() {
2065
+ this.image = null;
2066
+ this.file = null;
2067
+ }
2068
+ saveResource() {
2069
+ this.buttonBusy = true;
2070
+ this.saveTags(this.id);
2071
+ const payload = {
2072
+ ...this.editForm.value,
2073
+ subscription_id: this.subscriptionId
2074
+ };
2075
+ this.handlePicture(payload);
2076
+ this.handlePublishedAt(payload);
2077
+ this.handleAcceptedAt(payload);
2078
+ this.handleAcceptedAt(payload);
2079
+ this.handleOptionalFields(payload);
2080
+ this.handleRectangularPicture(payload);
2081
+ this.handleRemovals(payload);
2082
+ this.resourceService.updatePost(payload, this.id).subscribe(() => {
2083
+ this.buttonBusy = false;
2084
+ this.toast.success('Blog Post Updated');
2085
+ this.updated.emit();
2086
+ this.modalService.dismissAll();
2087
+ });
2088
+ }
2089
+ saveTags(id) {
2090
+ if (this.selectedTags.length) {
2091
+ const data = {
2092
+ entity_tags: this.selectedTags.map(tag => ({ tag_id: tag.id })),
2093
+ slug: id,
2094
+ tag_entity: 'Post' // or use TAG_ENTITY.POST if you imported it
2095
+ };
2096
+ this.tagService.addTags(data, this.subscriptionId).subscribe();
2097
+ }
2098
+ }
2099
+ handlePicture(data) {
2100
+ if (this.file) {
2101
+ data.picture = this.file;
2102
+ }
2103
+ else {
2104
+ delete data.picture;
2105
+ }
2106
+ }
2107
+ handlePublishedAt(data) {
2108
+ const control = this.editForm.get('published_at');
2109
+ if (control?.dirty) {
2110
+ data.published_at = control.value ? moment().format('DD-MMM-YYYY') : '';
2111
+ }
2112
+ else {
2113
+ delete data.published_at;
2114
+ }
2115
+ }
2116
+ handleAcceptedAt(data) {
2117
+ const control = this.editForm.get('accepted_at');
2118
+ if (control?.dirty) {
2119
+ data.accepted_at = control.value ? moment().format('DD-MMM-YYYY') : '';
2120
+ }
2121
+ else {
2122
+ delete data.accepted_at;
2123
+ }
2124
+ }
2125
+ handleOptionalFields(data) {
2126
+ if (!this.editForm.get('when')?.value) {
2127
+ data.when = '';
2128
+ }
2129
+ if (!this.editForm.get('showcase')?.value) {
2130
+ data.showcase = '';
2131
+ }
2132
+ }
2133
+ handleRectangularPicture(data) {
2134
+ if (this.rectangularFile) {
2135
+ data.rectangular_picture = this.rectangularFile;
2136
+ }
2137
+ else {
2138
+ delete data.rectangular_picture;
2139
+ }
2140
+ }
2141
+ handleRemovals(data) {
2142
+ if (!this.file && !this.image) {
2143
+ data.remove_picture = true;
2144
+ }
2145
+ if (!this.rectangularFile && !this.rectangularImage) {
2146
+ data.remove_rectangular_picture = true;
2147
+ }
2148
+ }
2149
+ openRectModal(content) {
2150
+ this.imageModalRef = this.modalService.open(content, {
2151
+ centered: true,
2152
+ windowClass: 'modal-holder'
2153
+ });
2154
+ }
2155
+ handleImageError(event, fallbackPath) {
2156
+ HelperService.handleImageFallbackPath(event, fallbackPath);
2157
+ }
2158
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceEditCardComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2$1.NgbModal }, { token: ResourceService }, { token: i2.AuthService }, { token: i2.TagService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); }
2159
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: ResourceEditCardComponent, selector: "pw-resource-edit-card", inputs: { id: "id", resourceData: "resourceData" }, outputs: { updated: "updated" }, usesInheritance: true, ngImport: i0, template: "<div class=\"edit-card\">\n <i class=\"fa fa-edit cursor-pointer text-dark in-page-edit-icon d-flex justify-content-center mb-2\"\n (click)=\"openModal(editResourceModal)\"\n (keydown.enter)=\"openModal(editResourceModal)\"\n (keydown.space)=\"openModal(editResourceModal)\"\n title=\"Edit Resource\"></i>\n</div>\n\n<ng-template #editResourceModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit Resource</h5>\n <i class=\"fa fa-edit cursor-pointer text-dark in-page-edit-icon d-flex justify-content-center ms-3\"\n (click)=\"navigateToResourceEdit()\"\n (keydown.enter)=\"navigateToResourceEdit()\"\n (keydown.space)=\"navigateToResourceEdit()\"\n title=\"Go to the main edit page\"></i>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n\n <div class=\"modal-body\">\n <form [formGroup]=\"editForm\">\n <div class=\"row\">\n\n\n <div class=\"col-12\">\n <pw-input-container label=\"Title\" name=\"title\">\n <input type=\"text\" class=\"form-control\" formControlName=\"title\" />\n </pw-input-container>\n </div>\n\n <div class=\"col-12 row\">\n <pw-input-container label=\"CTA Text\" name=\"cta_text\" class=\"col-md-6\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Resource.Posts.Tooltip.CtaText' | transloco\">\n <input type=\"text\" class=\"form-control\" formControlName=\"cta_text\" />\n </pw-input-container>\n\n <pw-input-container label=\"External URL\" name=\"external_url\" class=\"col-md-6\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Resource.Posts.Tooltip.ExternalUrl' | transloco\">\n <input type=\"text\" class=\"form-control\" formControlName=\"external_url\" />\n </pw-input-container>\n </div>\n\n <div class=\"col-12\">\n <pw-input-container\n [label]=\"'Resource.Posts.Body' | transloco\"\n name=\"body\"\n [errorMsg]=\"'Resource.Posts.Validation.Body' | transloco\">\n <quill-editor\n [styles]=\"{ height: '300px' }\"\n class=\"quillEditor\"\n [modules]=\"editorConfig\"\n formControlName=\"body\"\n [ngClass]=\"{\n 'w-100': true,\n 'quill-container': true,\n 'is-invalid': submitted && f['body'].errors\n }\">\n </quill-editor>\n </pw-input-container>\n </div>\n\n <div class=\"col-12 col-md-3 col-sm-6\">\n <pw-input-container\n [label]=\"'Resource.Posts.When' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Resource.Posts.Tooltip.When' | transloco\"\n name=\"when\">\n <p-calendar formControlName=\"when\"\n [showIcon]=\"true\"\n dateFormat=\"dd-M-yy\"\n [placeholder]=\"'Select Date'\"\n [ngClass]=\"{ 'is-invalid': submitted && f['when'].errors }\">\n </p-calendar>\n </pw-input-container>\n </div>\n\n <div class=\"col-12 col-md-8\">\n <pw-input-container\n [label]=\"'Resource.Posts.Tags' | transloco\"\n class=\"ui-fluid skills-modal tags\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Resource.Posts.Tooltip.CtaText' | transloco\"\n name=\"cta_text\">\n <p-autoComplete [(ngModel)]=\"selectedTags\"\n class=\"body-bg\"\n [suggestions]=\"tagsSuggestion\"\n dataKey=\"id\"\n field=\"name\"\n (completeMethod)=\"search($event)\"\n styleClass=\"w-100\"\n [minLength]=\"1\"\n [maxlength]=\"10\"\n [dropdown]=\"true\"\n [ngModelOptions]=\"{ standalone: true }\"\n placeholder=\"Tags\"\n [multiple]=\"true\">\n </p-autoComplete>\n </pw-input-container>\n </div>\n\n <div class=\"col-12 row\">\n <div class=\"col-md-4 col-sm-6\">\n <pw-input-container\n [label]=\"'SHOWCASE'\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Mark as showcase post'\"\n name=\"showcase\">\n <ui-switch formControlName=\"showcase\" class=\"d-block\"></ui-switch>\n </pw-input-container>\n </div>\n\n <div class=\"col-md-4 col-sm-6\">\n <pw-input-container\n [label]=\"'PUBLISHED'\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Set to publish the post'\"\n name=\"published_at\">\n <ui-switch formControlName=\"published_at\" class=\"d-block\"></ui-switch>\n </pw-input-container>\n </div>\n\n <div class=\"col-md-4 col-sm-6\">\n <pw-input-container\n [label]=\"'ACCEPTED BY ADMIN'\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Indicates approval by admin'\"\n name=\"accepted_at\">\n <ui-switch formControlName=\"accepted_at\" class=\"d-block\"></ui-switch>\n </pw-input-container>\n </div>\n </div>\n\n <div class=\"col-12 col-md-4 col-sm-4 my-4 ms-3\">\n <div class=\"text-center mb-4\">\n <label for=\"coverPicture\">{{ 'Resource.Posts.CoverPicture' | transloco }}</label>\n <div class=\"text-center d-flex flex-column align-items-center\">\n <img [src]=\"(image && !image.includes('default-photo.jpg')) ? image : 'assets/img/resource/blog.png'\"\n (click)=\"openImageModal(imageCropContent)\"\n (keydown.enter)=\"openImageModal(imageCropContent)\"\n class=\"image w-100\"\n alt=\"Modal\"\n (error)=\"handleImageError($event, 'assets/img/resource/blog.png')\" />\n <div class=\"d-flex justify-content-between align-items-center mt-2\">\n <a class=\"d-inline-block\" (click)=\"openImageModal(imageCropContent)\">\n {{ slug !== 'create' ? 'Edit' : 'Add' }} Picture\n </a>\n <i *ngIf=\"image && !image.includes('default-photo.jpg')\"\n class=\"fa fa-trash delete-icon text-danger ms-2 cursor-pointer\"\n title=\"Remove Image\"\n (click)=\"removeImage()\"\n (keydown.enter)=\"removeImage()\"></i>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"col-12 col-md-4 col-sm-4 my-4 ms-3\">\n <div class=\"text-center mb-4\">\n <label for=\"rectangularPicture\">Rectangular Picture</label>\n <div class=\"text-center d-flex flex-column align-items-center\">\n <img [src]=\"(rectangularImage && !rectangularImage.includes('default-photo.jpg')) ? rectangularImage : 'assets/img/resource/blog.png'\"\n (click)=\"openRectModal(rectContent)\"\n (keydown.enter)=\"openRectModal(rectContent)\"\n class=\"image w-100\"\n alt=\"Uploaded rectangular media preview\"\n (error)=\"handleImageError($event, 'assets/img/resource/blog.png')\" />\n <div class=\"d-flex justify-content-between align-items-center mt-2\">\n <a class=\"d-inline-block\" (click)=\"openRectModal(rectContent)\">\n {{ slug !== 'create' ? 'Edit' : 'Add' }} Picture\n </a>\n <i *ngIf=\"rectangularImage && !rectangularImage.includes('default-photo.jpg')\"\n class=\"fa fa-trash delete-icon text-danger ms-2 cursor-pointer\"\n title=\"Remove Image\"\n (click)=\"deleteRectangularImage()\"\n (keydown.enter)=\"deleteRectangularImage()\"></i>\n </div>\n </div>\n </div>\n </div>\n\n </div>\n </form>\n </div>\n\n <div class=\"modal-footer\">\n <button class=\"btn btn-secondary\" (click)=\"modal.dismiss()\">Cancel</button>\n <button class=\"btn btn-primary\" [buttonBusy]=\"buttonBusy\" (click)=\"saveResource()\">Save</button>\n </div>\n</ng-template>\n\n<ng-template #imageCropContent let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Upload Picture</h5>\n <button type=\"button\" class=\"btn-close\" (click)=\"modal.dismiss()\"></button>\n </div>\n <div class=\"modal-body\">\n <small>You can upload a JPG, GIF, or PNG file. (Do not upload pictures containing celebrities,\n nudity, artwork or copyrighted images.)</small>\n <pw-image-cropper\n [aspectRatio]=\"'dynamic'\"\n (imageSelectionEvent)=\"onImageSelected($event)\"\n (closeEvent)=\"modal.close()\">\n </pw-image-cropper>\n </div>\n</ng-template>\n\n<ng-template #rectContent let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Upload Picture</h5>\n <button type=\"button\" class=\"btn-close float-end\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n <div class=\"modal-body\">\n <small>You can upload a JPG, GIF, or PNG file. (Do not upload pictures containing celebrities,\n nudity, artwork or copyrighted images.)</small>\n <pw-image-cropper\n #profile\n [aspectRatio]=\"'dynamic'\"\n (imageSelectionEvent)=\"onRectangularImageSelection($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n</ng-template>\n", styles: ["::ng-deep .modal-content{margin-top:5rem!important}\n"], dependencies: [{ kind: "directive", type: i3$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i6$1.Calendar, selector: "p-calendar", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepYearPicker", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "component", type: i7$1.AutoComplete, selector: "p-autoComplete", inputs: ["minLength", "delay", "style", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "disabled", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "maxlength", "name", "required", "size", "appendTo", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "field", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "itemSize", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "variant"], outputs: ["completeMethod", "onSelect", "onUnselect", "onFocus", "onBlur", "onDropdownClick", "onClear", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "component", type: i6.ProfileImageCropperComponent, selector: "pw-image-cropper", inputs: ["aspectRatio", "dynamicData"], outputs: ["imageSelectionEvent", "closeEvent", "fileChangeEvent"] }, { kind: "component", type: i6.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "directive", type: i8.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i8.LazyImgDirective, selector: "img" }, { kind: "component", type: i10$1.QuillEditorComponent, selector: "quill-editor" }, { kind: "component", type: i11$1.UiSwitchComponent, selector: "ui-switch", inputs: ["size", "color", "switchOffColor", "switchColor", "defaultBgColor", "defaultBoColor", "checkedLabel", "uncheckedLabel", "checkedTextColor", "uncheckedTextColor", "beforeChange", "ariaLabel", "checked", "disabled", "reverse", "loading"], outputs: ["change", "changeEvent", "valueChange"] }, { kind: "pipe", type: i10.TranslocoPipe, name: "transloco" }] }); }
2160
+ }
2161
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceEditCardComponent, decorators: [{
2162
+ type: Component,
2163
+ args: [{ selector: 'pw-resource-edit-card', template: "<div class=\"edit-card\">\n <i class=\"fa fa-edit cursor-pointer text-dark in-page-edit-icon d-flex justify-content-center mb-2\"\n (click)=\"openModal(editResourceModal)\"\n (keydown.enter)=\"openModal(editResourceModal)\"\n (keydown.space)=\"openModal(editResourceModal)\"\n title=\"Edit Resource\"></i>\n</div>\n\n<ng-template #editResourceModal let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit Resource</h5>\n <i class=\"fa fa-edit cursor-pointer text-dark in-page-edit-icon d-flex justify-content-center ms-3\"\n (click)=\"navigateToResourceEdit()\"\n (keydown.enter)=\"navigateToResourceEdit()\"\n (keydown.space)=\"navigateToResourceEdit()\"\n title=\"Go to the main edit page\"></i>\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n\n <div class=\"modal-body\">\n <form [formGroup]=\"editForm\">\n <div class=\"row\">\n\n\n <div class=\"col-12\">\n <pw-input-container label=\"Title\" name=\"title\">\n <input type=\"text\" class=\"form-control\" formControlName=\"title\" />\n </pw-input-container>\n </div>\n\n <div class=\"col-12 row\">\n <pw-input-container label=\"CTA Text\" name=\"cta_text\" class=\"col-md-6\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Resource.Posts.Tooltip.CtaText' | transloco\">\n <input type=\"text\" class=\"form-control\" formControlName=\"cta_text\" />\n </pw-input-container>\n\n <pw-input-container label=\"External URL\" name=\"external_url\" class=\"col-md-6\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Resource.Posts.Tooltip.ExternalUrl' | transloco\">\n <input type=\"text\" class=\"form-control\" formControlName=\"external_url\" />\n </pw-input-container>\n </div>\n\n <div class=\"col-12\">\n <pw-input-container\n [label]=\"'Resource.Posts.Body' | transloco\"\n name=\"body\"\n [errorMsg]=\"'Resource.Posts.Validation.Body' | transloco\">\n <quill-editor\n [styles]=\"{ height: '300px' }\"\n class=\"quillEditor\"\n [modules]=\"editorConfig\"\n formControlName=\"body\"\n [ngClass]=\"{\n 'w-100': true,\n 'quill-container': true,\n 'is-invalid': submitted && f['body'].errors\n }\">\n </quill-editor>\n </pw-input-container>\n </div>\n\n <div class=\"col-12 col-md-3 col-sm-6\">\n <pw-input-container\n [label]=\"'Resource.Posts.When' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Resource.Posts.Tooltip.When' | transloco\"\n name=\"when\">\n <p-calendar formControlName=\"when\"\n [showIcon]=\"true\"\n dateFormat=\"dd-M-yy\"\n [placeholder]=\"'Select Date'\"\n [ngClass]=\"{ 'is-invalid': submitted && f['when'].errors }\">\n </p-calendar>\n </pw-input-container>\n </div>\n\n <div class=\"col-12 col-md-8\">\n <pw-input-container\n [label]=\"'Resource.Posts.Tags' | transloco\"\n class=\"ui-fluid skills-modal tags\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Resource.Posts.Tooltip.CtaText' | transloco\"\n name=\"cta_text\">\n <p-autoComplete [(ngModel)]=\"selectedTags\"\n class=\"body-bg\"\n [suggestions]=\"tagsSuggestion\"\n dataKey=\"id\"\n field=\"name\"\n (completeMethod)=\"search($event)\"\n styleClass=\"w-100\"\n [minLength]=\"1\"\n [maxlength]=\"10\"\n [dropdown]=\"true\"\n [ngModelOptions]=\"{ standalone: true }\"\n placeholder=\"Tags\"\n [multiple]=\"true\">\n </p-autoComplete>\n </pw-input-container>\n </div>\n\n <div class=\"col-12 row\">\n <div class=\"col-md-4 col-sm-6\">\n <pw-input-container\n [label]=\"'SHOWCASE'\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Mark as showcase post'\"\n name=\"showcase\">\n <ui-switch formControlName=\"showcase\" class=\"d-block\"></ui-switch>\n </pw-input-container>\n </div>\n\n <div class=\"col-md-4 col-sm-6\">\n <pw-input-container\n [label]=\"'PUBLISHED'\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Set to publish the post'\"\n name=\"published_at\">\n <ui-switch formControlName=\"published_at\" class=\"d-block\"></ui-switch>\n </pw-input-container>\n </div>\n\n <div class=\"col-md-4 col-sm-6\">\n <pw-input-container\n [label]=\"'ACCEPTED BY ADMIN'\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Indicates approval by admin'\"\n name=\"accepted_at\">\n <ui-switch formControlName=\"accepted_at\" class=\"d-block\"></ui-switch>\n </pw-input-container>\n </div>\n </div>\n\n <div class=\"col-12 col-md-4 col-sm-4 my-4 ms-3\">\n <div class=\"text-center mb-4\">\n <label for=\"coverPicture\">{{ 'Resource.Posts.CoverPicture' | transloco }}</label>\n <div class=\"text-center d-flex flex-column align-items-center\">\n <img [src]=\"(image && !image.includes('default-photo.jpg')) ? image : 'assets/img/resource/blog.png'\"\n (click)=\"openImageModal(imageCropContent)\"\n (keydown.enter)=\"openImageModal(imageCropContent)\"\n class=\"image w-100\"\n alt=\"Modal\"\n (error)=\"handleImageError($event, 'assets/img/resource/blog.png')\" />\n <div class=\"d-flex justify-content-between align-items-center mt-2\">\n <a class=\"d-inline-block\" (click)=\"openImageModal(imageCropContent)\">\n {{ slug !== 'create' ? 'Edit' : 'Add' }} Picture\n </a>\n <i *ngIf=\"image && !image.includes('default-photo.jpg')\"\n class=\"fa fa-trash delete-icon text-danger ms-2 cursor-pointer\"\n title=\"Remove Image\"\n (click)=\"removeImage()\"\n (keydown.enter)=\"removeImage()\"></i>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"col-12 col-md-4 col-sm-4 my-4 ms-3\">\n <div class=\"text-center mb-4\">\n <label for=\"rectangularPicture\">Rectangular Picture</label>\n <div class=\"text-center d-flex flex-column align-items-center\">\n <img [src]=\"(rectangularImage && !rectangularImage.includes('default-photo.jpg')) ? rectangularImage : 'assets/img/resource/blog.png'\"\n (click)=\"openRectModal(rectContent)\"\n (keydown.enter)=\"openRectModal(rectContent)\"\n class=\"image w-100\"\n alt=\"Uploaded rectangular media preview\"\n (error)=\"handleImageError($event, 'assets/img/resource/blog.png')\" />\n <div class=\"d-flex justify-content-between align-items-center mt-2\">\n <a class=\"d-inline-block\" (click)=\"openRectModal(rectContent)\">\n {{ slug !== 'create' ? 'Edit' : 'Add' }} Picture\n </a>\n <i *ngIf=\"rectangularImage && !rectangularImage.includes('default-photo.jpg')\"\n class=\"fa fa-trash delete-icon text-danger ms-2 cursor-pointer\"\n title=\"Remove Image\"\n (click)=\"deleteRectangularImage()\"\n (keydown.enter)=\"deleteRectangularImage()\"></i>\n </div>\n </div>\n </div>\n </div>\n\n </div>\n </form>\n </div>\n\n <div class=\"modal-footer\">\n <button class=\"btn btn-secondary\" (click)=\"modal.dismiss()\">Cancel</button>\n <button class=\"btn btn-primary\" [buttonBusy]=\"buttonBusy\" (click)=\"saveResource()\">Save</button>\n </div>\n</ng-template>\n\n<ng-template #imageCropContent let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Upload Picture</h5>\n <button type=\"button\" class=\"btn-close\" (click)=\"modal.dismiss()\"></button>\n </div>\n <div class=\"modal-body\">\n <small>You can upload a JPG, GIF, or PNG file. (Do not upload pictures containing celebrities,\n nudity, artwork or copyrighted images.)</small>\n <pw-image-cropper\n [aspectRatio]=\"'dynamic'\"\n (imageSelectionEvent)=\"onImageSelected($event)\"\n (closeEvent)=\"modal.close()\">\n </pw-image-cropper>\n </div>\n</ng-template>\n\n<ng-template #rectContent let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Upload Picture</h5>\n <button type=\"button\" class=\"btn-close float-end\" aria-label=\"Close\" (click)=\"modal.dismiss()\"></button>\n </div>\n <div class=\"modal-body\">\n <small>You can upload a JPG, GIF, or PNG file. (Do not upload pictures containing celebrities,\n nudity, artwork or copyrighted images.)</small>\n <pw-image-cropper\n #profile\n [aspectRatio]=\"'dynamic'\"\n (imageSelectionEvent)=\"onRectangularImageSelection($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n</ng-template>\n", styles: ["::ng-deep .modal-content{margin-top:5rem!important}\n"] }]
2164
+ }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i2$1.NgbModal }, { type: ResourceService }, { type: i2.AuthService }, { type: i2.TagService }, { type: i0.Injector }], propDecorators: { id: [{
2165
+ type: Input
2166
+ }], resourceData: [{
2167
+ type: Input
2168
+ }], updated: [{
2169
+ type: Output
2170
+ }] } });
2171
+
2172
+ var resourceEditCard_component = /*#__PURE__*/Object.freeze({
2173
+ __proto__: null,
2174
+ ResourceEditCardComponent: ResourceEditCardComponent
2175
+ });
2176
+
2177
+ /**
2178
+ * Lazy-loadable module for ResourceEditCard
2179
+ * Contains heavy dependencies (Quill, Calendar, etc.) that are only needed for admins
2180
+ * This module is dynamically imported when edit button is clicked
2181
+ */
2182
+ class ResourceEditModule {
2183
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceEditModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2184
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.11", ngImport: i0, type: ResourceEditModule, declarations: [ResourceEditCardComponent], imports: [CommonModule,
2185
+ FormsModule,
2186
+ ReactiveFormsModule,
2187
+ CalendarModule,
2188
+ AutoCompleteModule,
2189
+ ResourceSharedComponentsModule,
2190
+ CoreTranslocoModule,
2191
+ TranslocoModule,
2192
+ DirectivesModule, i10$1.QuillModule, UiSwitchModule], exports: [ResourceEditCardComponent] }); }
2193
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceEditModule, imports: [CommonModule,
2194
+ FormsModule,
2195
+ ReactiveFormsModule,
2196
+ CalendarModule,
2197
+ AutoCompleteModule,
2198
+ ResourceSharedComponentsModule,
2199
+ CoreTranslocoModule,
2200
+ TranslocoModule,
2201
+ DirectivesModule,
2202
+ QuillModule.forRoot(),
2203
+ UiSwitchModule] }); }
2204
+ }
2205
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ResourceEditModule, decorators: [{
2206
+ type: NgModule,
2207
+ args: [{
2208
+ declarations: [ResourceEditCardComponent],
2209
+ imports: [
2210
+ CommonModule,
2211
+ FormsModule,
2212
+ ReactiveFormsModule,
2213
+ CalendarModule,
2214
+ AutoCompleteModule,
2215
+ ResourceSharedComponentsModule,
2216
+ CoreTranslocoModule,
2217
+ TranslocoModule,
2218
+ DirectivesModule,
2219
+ QuillModule.forRoot(),
2220
+ UiSwitchModule
2221
+ ],
2222
+ exports: [ResourceEditCardComponent],
2223
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
2224
+ }]
2225
+ }] });
2226
+
2227
+ class TestimonialCardListComponent {
2228
+ constructor() {
2229
+ this.editPost = new EventEmitter();
2230
+ this.posts = [];
2231
+ this.postHeader = '';
2232
+ this.canEdit = false;
2233
+ }
2234
+ ngOnChanges(changes) {
2235
+ if (changes.posts && this.posts?.length) {
2236
+ setTimeout(() => this.initSwiper(), 0); // Wait for DOM to render
2237
+ }
2238
+ }
2239
+ async initSwiper() {
2240
+ // Dynamically import Swiper only when needed (lazy-load ~150KB library)
2241
+ const { default: Swiper, Navigation, Pagination } = await import('swiper');
2242
+ this.swiper = new Swiper('.swiper-container', {
2243
+ modules: [Navigation, Pagination],
2244
+ slidesPerView: 1,
2245
+ spaceBetween: 24,
2246
+ centeredSlides: true,
2247
+ touchRatio: 1,
2248
+ touchAngle: 45,
2249
+ grabCursor: true,
2250
+ navigation: {
2251
+ nextEl: '.swiper-button-next',
2252
+ prevEl: '.swiper-button-prev'
2253
+ },
2254
+ pagination: {
2255
+ el: '.swiper-pagination',
2256
+ clickable: true
2257
+ },
2258
+ breakpoints: {
2259
+ 425: {
2260
+ slidesPerView: 1.05,
2261
+ centeredSlides: true
2262
+ },
2263
+ 470: {
2264
+ slidesPerView: 1.25,
2265
+ centeredSlides: true
2266
+ },
2267
+ 564: {
2268
+ slidesPerView: 1.5,
2269
+ centeredSlides: true
2270
+ },
2271
+ 640: {
2272
+ slidesPerView: 1.5,
2273
+ centeredSlides: true
2274
+ },
2275
+ 768: {
2276
+ slidesPerView: 1.5,
2277
+ centeredSlides: true
2278
+ },
2279
+ 1024: {
2280
+ slidesPerView: 2, // Allow room between cards
2281
+ centeredSlides: false
2282
+ },
2283
+ 1200: {
2284
+ slidesPerView: 3,
2285
+ centeredSlides: false
2286
+ }
2287
+ }
2288
+ });
2289
+ }
2290
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: TestimonialCardListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2291
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: TestimonialCardListComponent, selector: "pw-testimonial-card", inputs: { posts: "posts", postHeader: "postHeader", canEdit: "canEdit" }, outputs: { editPost: "editPost" }, usesOnChanges: true, ngImport: i0, template: "<section class=\"resource-section section-outer bg-white\">\n <div class=\"container\">\n <div *ngIf=\"postHeader\" class=\"d-flex justify-content-between align-items-center flex-wrap mb-3\">\n <h2 class=\"section-heading\">{{postHeader}}</h2>\n </div>\n <div *ngIf=\"posts.length === 0\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n<div [hidden]=\"posts.length === 0\">\n <div class=\"swiper-container\">\n <div class=\"swiper-wrapper\">\n <div class=\"swiper-slide\" *ngFor=\"let post of posts\">\n <div class=\"testimonial-box\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEdit\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"editPost.emit(1, 100)\">\n </pw-resource-edit-card-lazy>\n <div class=\"stars mb-5\">\u2605\u2605\u2605\u2605\u2605</div>\n <div class=\"testimonial-content\">\n <div class=\"ql-container ql-snow ql-res\">\n <div class=\"ql-editor\"\n [innerHTML]=\"post?.body\">\n </div>\n </div>\n </div>\n\n <!-- THIS STAYS AT BOTTOM -->\n <div class=\"avatar-container\">\n <img\n *ngIf=\"!post.rectangular_picture.url.includes('default-photo.jpg') \" [src]=\"post.rectangular_picture.url\"\n alt=\"Logo\"\n class=\"testimonial-logo mt-4\"\n />\n </div>\n </div>\n\n </div>\n </div>\n <div class=\"swiper-pagination\"></div>\n <div class=\"swiper-button-prev\"></div>\n <div class=\"swiper-button-next\"></div>\n </div>\n</div>\n </div>\n</section>", styles: [".resource-section{box-shadow:0 4px 32px -14px #40576d4d!important;position:relative}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 767px){.container{padding:0 1rem!important}}.ql-res{resize:none!important;border-width:0}.swiper-container{padding:20px;position:relative;overflow:hidden}@media (width >= 768px){.swiper-container{padding:20px 40px}}.resource-card{background:#fff;border-radius:8px;box-shadow:0 0 20px #0000001a;padding:1.5rem;height:100%;display:flex;flex-direction:column;margin:0 auto;width:100%;max-width:350px}.resource-title{font-size:1.25rem;font-weight:600;margin-bottom:1rem}.resource-image{width:100%;aspect-ratio:1/1;object-fit:cover;border-radius:4px}.read-now-btn{margin-top:auto;display:inline-flex;align-items:center;gap:.5rem;color:#000;text-decoration:none;font-weight:500}.read-now-btn .arrow{transition:transform .2s ease}.read-now-btn:hover .arrow{transform:translate(5px)}.swiper-button-prev,.swiper-button-next{color:#000}.swiper-button-prev:after,.swiper-button-next:after{font-size:24px}@media (width <= 767px){.swiper-button-prev,.swiper-button-next{display:none}}.swiper-pagination{position:relative;margin-top:20px}.swiper-pagination-bullet{background:#000;opacity:.5}.swiper-pagination-bullet-active{opacity:1}.swiper-wrapper{display:flex;align-items:stretch}.swiper-slide{display:flex;align-items:stretch;height:auto}.testimonial-box{display:flex;flex-direction:column;justify-content:space-between;background:#fff;border-radius:20px;padding:2.5rem 1.5rem;box-shadow:0 0 20px #0000001a;text-align:center;width:338px;font-size:1.1rem;height:100%;min-height:100%}.testimonial-box span{margin:0;font-size:22px}.testimonial-box .avatar-container{margin-top:auto}.testimonial-box .testimonial-logo{width:100%!important;height:auto!important;max-width:150px!important;object-fit:contain;align-self:center}.testimonial-box .stars{font-size:2.2rem;color:#f6b300;margin-bottom:2.5rem}.centaris-text{margin-bottom:3rem!important}@media (width <= 768px){::ng-deep .swiper-wrapper{gap:1rem!important}.testimonial-box{width:300px!important}}\n", ".video-row{gap:5.5rem!important;margin-top:3rem!important}::ng-deep .resource-section{box-shadow:0 4px 32px -14px #40576d4d!important}.release-icon{height:auto;margin:0 11px 1.9rem;display:block;align-self:center}@media (width >= 768px) and (width <= 1200px){.resource-title{font-size:1.4rem!important}}textarea{font-size:1.4rem!important}@media (width <= 768px){.resource-title{font-size:1.2rem!important}.container{padding:1rem!important}}@media (width >= 768px) and (width <= 1200px){.container{padding:1rem 3rem!important}}@media (width <= 1200px){.resource-vault-section .vault-heading{font-size:3.5rem}.resource-vault-section .vault-description{margin-top:1.35rem}.resource-vault-section .vault-card{width:100%!important}.resource-vault-section .vault-btn{margin-left:0!important;width:100%!important}}@media (width >= 991px){::ng-deep .trial-meeting-section:before{top:600px!important}::ng-deep .dashboard{margin-bottom:1rem!important}section.bg-white.text-center.extra-top-padding{position:relative;overflow:hidden}section.bg-white.text-center.extra-top-padding .banner-header{margin-bottom:4rem!important}section.bg-white.text-center.extra-top-padding:before,section.bg-white.text-center.extra-top-padding:after{content:\"\";position:absolute;background:url(/assets/img/logos/background-banner.png) no-repeat;background-size:contain;width:160px;height:450px;z-index:0;opacity:.8}section.bg-white.text-center.extra-top-padding:before{top:500px;left:0}section.bg-white.text-center.extra-top-padding:after{top:90px;right:0}}.vault-header{text-align:left}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 1200px){.resource-card{width:100%!important}.release-notes-section{padding:7rem 0!important}}@media (width >= 768px) and (width <= 1200px){.resource-hero-section{padding:0 6rem!important}.cards-row{justify-content:center}}.resource-body-section{background-color:#fff}.resource-body-section .container{padding:0 1.5rem;padding-bottom:4rem!important;padding-top:7rem!important;max-width:850px;margin:0 auto;text-align:left}.user-not-logged-in{background:#f7f7f7;border:1px solid rgb(238,238,238);font-weight:400}.user-not-logged-in a{color:var(--first)!important;text-decoration:none;font-weight:500}.resource-book-section{background:#fff;padding-top:7rem;padding-bottom:0}.resource-book-section .container{max-width:850px;margin:0 auto;padding:0 2rem!important;text-align:left}.resource-book-section .resource-contact{line-height:1.6;font-size:1.5rem}.resource-book-section .resource-contact a{text-decoration:underline;color:#000;margin:0 .2rem}.resource-book-section .resource-contact a:hover{color:var(--first)!important}.resource-offer-section{background:#fff;padding-top:2rem}.resource-offer-section .container{max-width:850px;margin:0 auto;padding:0 1.5rem;text-align:left}.resource-offer-section .resource-title{font-size:2rem;font-weight:700;color:#000;margin-bottom:.25em!important}.resource-offer-section .resource-title strong{font-weight:700}.resource-offer-section .resource-description{font-size:1.5rem;line-height:1.8rem;color:#333;margin-bottom:1.5rem}.resource-offer-section .resource-offer-list{font-size:1.1rem;line-height:1.5rem;margin-bottom:2.5rem;margin-top:2.5rem}.resource-offer-section .resource-offer-list p{font-size:1.5rem;margin:.5rem 0;font-weight:400}.resource-offer-section .resource-signup{margin-bottom:2.5rem}.resource-offer-section .resource-signup .signup-link{font-size:1.5rem;font-weight:400;text-decoration:underline;color:#000}@media (width <= 768px){.resource-offer-section .resource-book-section{padding-top:2rem!important}.resource-offer-section .container{text-align:left}.resource-offer-section .resource-title{font-size:1.5rem}.resource-offer-section .resource-description,.resource-offer-section .resource-offer-list,.resource-offer-section .resource-signup,.resource-offer-section .signup-link,.resource-offer-section .resource-contact,.resource-offer-section .resource-offer-list p{font-size:1.2rem!important}}.resource-offer-intro{font-size:1.5rem;font-weight:400}.outer-section-fadeout{position:absolute;top:139rem;height:40px;width:100%;background:linear-gradient(to bottom,#fff0,#f8f9fa)}.body-divider{border:0;height:40px;width:100%;background:linear-gradient(to bottom,#0000,#00000026);margin:0}@media (width <= 768px){.resource-book-section{padding-top:2rem!important}.resource-contact{font-size:1.2rem!important}}::ng-deep .body-quill{border-width:0!important;max-width:900px;display:block;margin-left:auto;margin-right:auto}::ng-deep .p-inputtextarea{border-radius:.5rem;border-color:#ced4da;font-size:1rem}.card{background-color:#fff;border-radius:12px}.comment-row{gap:2rem;padding-bottom:5rem;max-width:1000px;display:block;margin-left:auto;margin-right:auto}.comment-label{font-size:1.5rem!important}.response-row{max-width:1000px;display:block;margin-left:auto;margin-right:auto;margin-top:3rem!important}\n"], dependencies: [{ kind: "component", type: ResourceEditCardLazyComponent, selector: "pw-resource-edit-card-lazy", inputs: ["id", "resourceData", "canEdit"], outputs: ["updated"] }, { kind: "directive", type: i3$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "directive", type: i8.LazyImgDirective, selector: "img" }, { kind: "pipe", type: i10.TranslocoPipe, name: "transloco" }] }); }
2292
+ }
2293
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: TestimonialCardListComponent, decorators: [{
2294
+ type: Component,
2295
+ args: [{ selector: 'pw-testimonial-card', template: "<section class=\"resource-section section-outer bg-white\">\n <div class=\"container\">\n <div *ngIf=\"postHeader\" class=\"d-flex justify-content-between align-items-center flex-wrap mb-3\">\n <h2 class=\"section-heading\">{{postHeader}}</h2>\n </div>\n <div *ngIf=\"posts.length === 0\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Resource.NoDataMessage' | transloco\"/>\n </div>\n<div [hidden]=\"posts.length === 0\">\n <div class=\"swiper-container\">\n <div class=\"swiper-wrapper\">\n <div class=\"swiper-slide\" *ngFor=\"let post of posts\">\n <div class=\"testimonial-box\">\n <pw-resource-edit-card-lazy\n [canEdit]=\"canEdit\"\n [id]=\"post.id\"\n [resourceData]=\"post\"\n (updated)=\"editPost.emit(1, 100)\">\n </pw-resource-edit-card-lazy>\n <div class=\"stars mb-5\">\u2605\u2605\u2605\u2605\u2605</div>\n <div class=\"testimonial-content\">\n <div class=\"ql-container ql-snow ql-res\">\n <div class=\"ql-editor\"\n [innerHTML]=\"post?.body\">\n </div>\n </div>\n </div>\n\n <!-- THIS STAYS AT BOTTOM -->\n <div class=\"avatar-container\">\n <img\n *ngIf=\"!post.rectangular_picture.url.includes('default-photo.jpg') \" [src]=\"post.rectangular_picture.url\"\n alt=\"Logo\"\n class=\"testimonial-logo mt-4\"\n />\n </div>\n </div>\n\n </div>\n </div>\n <div class=\"swiper-pagination\"></div>\n <div class=\"swiper-button-prev\"></div>\n <div class=\"swiper-button-next\"></div>\n </div>\n</div>\n </div>\n</section>", styles: [".resource-section{box-shadow:0 4px 32px -14px #40576d4d!important;position:relative}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 767px){.container{padding:0 1rem!important}}.ql-res{resize:none!important;border-width:0}.swiper-container{padding:20px;position:relative;overflow:hidden}@media (width >= 768px){.swiper-container{padding:20px 40px}}.resource-card{background:#fff;border-radius:8px;box-shadow:0 0 20px #0000001a;padding:1.5rem;height:100%;display:flex;flex-direction:column;margin:0 auto;width:100%;max-width:350px}.resource-title{font-size:1.25rem;font-weight:600;margin-bottom:1rem}.resource-image{width:100%;aspect-ratio:1/1;object-fit:cover;border-radius:4px}.read-now-btn{margin-top:auto;display:inline-flex;align-items:center;gap:.5rem;color:#000;text-decoration:none;font-weight:500}.read-now-btn .arrow{transition:transform .2s ease}.read-now-btn:hover .arrow{transform:translate(5px)}.swiper-button-prev,.swiper-button-next{color:#000}.swiper-button-prev:after,.swiper-button-next:after{font-size:24px}@media (width <= 767px){.swiper-button-prev,.swiper-button-next{display:none}}.swiper-pagination{position:relative;margin-top:20px}.swiper-pagination-bullet{background:#000;opacity:.5}.swiper-pagination-bullet-active{opacity:1}.swiper-wrapper{display:flex;align-items:stretch}.swiper-slide{display:flex;align-items:stretch;height:auto}.testimonial-box{display:flex;flex-direction:column;justify-content:space-between;background:#fff;border-radius:20px;padding:2.5rem 1.5rem;box-shadow:0 0 20px #0000001a;text-align:center;width:338px;font-size:1.1rem;height:100%;min-height:100%}.testimonial-box span{margin:0;font-size:22px}.testimonial-box .avatar-container{margin-top:auto}.testimonial-box .testimonial-logo{width:100%!important;height:auto!important;max-width:150px!important;object-fit:contain;align-self:center}.testimonial-box .stars{font-size:2.2rem;color:#f6b300;margin-bottom:2.5rem}.centaris-text{margin-bottom:3rem!important}@media (width <= 768px){::ng-deep .swiper-wrapper{gap:1rem!important}.testimonial-box{width:300px!important}}\n", ".video-row{gap:5.5rem!important;margin-top:3rem!important}::ng-deep .resource-section{box-shadow:0 4px 32px -14px #40576d4d!important}.release-icon{height:auto;margin:0 11px 1.9rem;display:block;align-self:center}@media (width >= 768px) and (width <= 1200px){.resource-title{font-size:1.4rem!important}}textarea{font-size:1.4rem!important}@media (width <= 768px){.resource-title{font-size:1.2rem!important}.container{padding:1rem!important}}@media (width >= 768px) and (width <= 1200px){.container{padding:1rem 3rem!important}}@media (width <= 1200px){.resource-vault-section .vault-heading{font-size:3.5rem}.resource-vault-section .vault-description{margin-top:1.35rem}.resource-vault-section .vault-card{width:100%!important}.resource-vault-section .vault-btn{margin-left:0!important;width:100%!important}}@media (width >= 991px){::ng-deep .trial-meeting-section:before{top:600px!important}::ng-deep .dashboard{margin-bottom:1rem!important}section.bg-white.text-center.extra-top-padding{position:relative;overflow:hidden}section.bg-white.text-center.extra-top-padding .banner-header{margin-bottom:4rem!important}section.bg-white.text-center.extra-top-padding:before,section.bg-white.text-center.extra-top-padding:after{content:\"\";position:absolute;background:url(/assets/img/logos/background-banner.png) no-repeat;background-size:contain;width:160px;height:450px;z-index:0;opacity:.8}section.bg-white.text-center.extra-top-padding:before{top:500px;left:0}section.bg-white.text-center.extra-top-padding:after{top:90px;right:0}}.vault-header{text-align:left}@media (width >= 768px) and (width <= 1200px){.container{padding:0 6rem!important}}@media (width <= 1200px){.resource-card{width:100%!important}.release-notes-section{padding:7rem 0!important}}@media (width >= 768px) and (width <= 1200px){.resource-hero-section{padding:0 6rem!important}.cards-row{justify-content:center}}.resource-body-section{background-color:#fff}.resource-body-section .container{padding:0 1.5rem;padding-bottom:4rem!important;padding-top:7rem!important;max-width:850px;margin:0 auto;text-align:left}.user-not-logged-in{background:#f7f7f7;border:1px solid rgb(238,238,238);font-weight:400}.user-not-logged-in a{color:var(--first)!important;text-decoration:none;font-weight:500}.resource-book-section{background:#fff;padding-top:7rem;padding-bottom:0}.resource-book-section .container{max-width:850px;margin:0 auto;padding:0 2rem!important;text-align:left}.resource-book-section .resource-contact{line-height:1.6;font-size:1.5rem}.resource-book-section .resource-contact a{text-decoration:underline;color:#000;margin:0 .2rem}.resource-book-section .resource-contact a:hover{color:var(--first)!important}.resource-offer-section{background:#fff;padding-top:2rem}.resource-offer-section .container{max-width:850px;margin:0 auto;padding:0 1.5rem;text-align:left}.resource-offer-section .resource-title{font-size:2rem;font-weight:700;color:#000;margin-bottom:.25em!important}.resource-offer-section .resource-title strong{font-weight:700}.resource-offer-section .resource-description{font-size:1.5rem;line-height:1.8rem;color:#333;margin-bottom:1.5rem}.resource-offer-section .resource-offer-list{font-size:1.1rem;line-height:1.5rem;margin-bottom:2.5rem;margin-top:2.5rem}.resource-offer-section .resource-offer-list p{font-size:1.5rem;margin:.5rem 0;font-weight:400}.resource-offer-section .resource-signup{margin-bottom:2.5rem}.resource-offer-section .resource-signup .signup-link{font-size:1.5rem;font-weight:400;text-decoration:underline;color:#000}@media (width <= 768px){.resource-offer-section .resource-book-section{padding-top:2rem!important}.resource-offer-section .container{text-align:left}.resource-offer-section .resource-title{font-size:1.5rem}.resource-offer-section .resource-description,.resource-offer-section .resource-offer-list,.resource-offer-section .resource-signup,.resource-offer-section .signup-link,.resource-offer-section .resource-contact,.resource-offer-section .resource-offer-list p{font-size:1.2rem!important}}.resource-offer-intro{font-size:1.5rem;font-weight:400}.outer-section-fadeout{position:absolute;top:139rem;height:40px;width:100%;background:linear-gradient(to bottom,#fff0,#f8f9fa)}.body-divider{border:0;height:40px;width:100%;background:linear-gradient(to bottom,#0000,#00000026);margin:0}@media (width <= 768px){.resource-book-section{padding-top:2rem!important}.resource-contact{font-size:1.2rem!important}}::ng-deep .body-quill{border-width:0!important;max-width:900px;display:block;margin-left:auto;margin-right:auto}::ng-deep .p-inputtextarea{border-radius:.5rem;border-color:#ced4da;font-size:1rem}.card{background-color:#fff;border-radius:12px}.comment-row{gap:2rem;padding-bottom:5rem;max-width:1000px;display:block;margin-left:auto;margin-right:auto}.comment-label{font-size:1.5rem!important}.response-row{max-width:1000px;display:block;margin-left:auto;margin-right:auto;margin-top:3rem!important}\n"] }]
2296
+ }], propDecorators: { editPost: [{
2297
+ type: Output
2298
+ }], posts: [{
2299
+ type: Input
2300
+ }], postHeader: [{
2301
+ type: Input
2302
+ }], canEdit: [{
2303
+ type: Input
2304
+ }] } });
2305
+
2306
+ /**
2307
+ * Generated bundle index. Do not edit.
2308
+ */
2309
+
2310
+ export { BaseResourceComponent as B, CaseStudyCardComponent as C, ResourceVideoCardComponent as R, Trial4ContactUsComponent as T, UpcomingEventCardComponent as U, ResourceCardComponent as a, ResourceNoteCardComponent as b, ResourceVaultComponent as c, ResourceCardsModule as d, ResourceService as e, ResourceEditCardLazyComponent as f, ResourceSharedModule as g, ResourceTopBannerEditComponent as h, ResourceCompanyCardComponent as i, TestimonialCardListComponent as j, ResourceModule as k, Trial4ContactUsModule as l, ResourcePublicModule as m, ResourceEditModule as n, ResourceEditCardComponent as o };
2311
+ //# sourceMappingURL=posiwise-resource-module-posiwise-resource-module-D953ymF3.mjs.map