Error compiling template "Designs/Swift/Paragraph/Finixa_ProductDetailsMediaTable.cshtml"
Line 567: } expected
Line 567: } expected
Line 567: } expected
Line 567: } expected
Line 567: } expected
Line 353: The name 'RenderAsset' does not exist in the current context
Line 357: The name 'languageId' does not exist in the current context
Line 507: A local or parameter named 'asset' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
Line 509: A local or parameter named 'assetName' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
Line 170: The variable 'videoNumber' is assigned but its value is never used
Line 178: The variable 'iconPath' is assigned but its value is never used
1 // <auto-generated/>
2 #pragma warning disable 1591
3 namespace CompiledRazorTemplates.Dynamic
4 {
5 #line hidden
6 using System.Threading.Tasks;
7 using System;
8 using System.Collections.Generic;
9 using System.Linq;
10 using Dynamicweb.Ecommerce.ProductCatalog;
11 using System.Text.RegularExpressions;
12 using System.IO;
13 internal class RazorEngine_e8d49be7265f46538dfdcf66f670f2ac : Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel>
14 {
15 #pragma warning disable 1998
16 public async override global::System.Threading.Tasks.Task ExecuteAsync()
17 {
18
19 ProductViewModel product = null;
20 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
21 {
22 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
23 }
24 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode)
25 {
26 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page);
27 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel();
28 if (productList?.Products is object)
29 {
30 product = productList.Products[0];
31 }
32 }
33 string siteLanguage = Pageview.Area.CultureInfo.Name;
34
35
36 int pageId = Dynamicweb.Context.Current.Request["CurrentPageID"] != null ? Convert.ToInt32(Dynamicweb.Context.Current.Request["CurrentPageID"]) : Pageview.ID;
37 var currentPage = Dynamicweb.Content.Services.Pages.GetPage(pageId);
38 List<Dynamicweb.Content.Page> websiteLanguages = new List<Dynamicweb.Content.Page>();
39 if (currentPage.Area.IsMaster)
40 {
41 websiteLanguages.Add(currentPage); // Add master language
42 if (currentPage.Languages != null)
43 {
44 foreach (var lang in currentPage.Languages)
45 {
46 if (lang.Area.Active == true) // Filter active languages
47 {
48 websiteLanguages.Add(lang);
49 }
50 }
51 }
52 }
53 else
54 {
55 websiteLanguages.Add(currentPage.MasterPage); // Add master page
56 if (currentPage.MasterPage != null && currentPage.MasterPage.Languages != null)
57 {
58 foreach (var lang in currentPage.MasterPage.Languages)
59 {
60 if (lang.Area.Active == true)
61 {
62 websiteLanguages.Add(lang);
63 }
64 }
65 }
66 }
67
68
69 var ecomLanguages = Dynamicweb.Ecommerce.Services.Languages.GetLanguages();
70 List<Dynamicweb.Ecommerce.International.Language> activeLanguages = new List<Dynamicweb.Ecommerce.International.Language>();
71
72
73 foreach (var websiteLanguage in websiteLanguages)
74 {
75 var matchingEcomLanguage = ecomLanguages.FirstOrDefault(ecomLang =>
76 string.Equals(ecomLang.Culture, websiteLanguage.Area.CultureInfo.Name, StringComparison.OrdinalIgnoreCase) ||
77 string.Equals(ecomLang.Code, websiteLanguage.Area.CultureInfo.TwoLetterISOLanguageName, StringComparison.OrdinalIgnoreCase));
78
79 if (matchingEcomLanguage != null && !activeLanguages.Contains(matchingEcomLanguage))
80 {
81 activeLanguages.Add(matchingEcomLanguage);
82 }
83 }
84
85 if (activeLanguages.Count == 0)
86 {
87 activeLanguages = ecomLanguages.ToList();
88 }
89 if (product is object)
90 {
91
92 supportedImageFormats = new string[] { ".jpg", ".jpeg", ".webp", ".png", ".gif", ".bmp", ".tiff" };
93 supportedVideoFormats = new string[] { "youtu.be", "youtube", "vimeo", ".mp4", ".webm" };
94 supportedDocumentFormats = new string[] { ".pdf", ".docx", ".xlsx", ".ppt", ".pptx", ".igs", ".ipt", ".sat", ".stp", ".dwg", ".dxf", ".dwf" };
95 allSupportedFormats = supportedImageFormats.Concat(supportedVideoFormats).Concat(supportedDocumentFormats).ToArray();
96
97
98 var selectedAssetCategories = Model.Item.GetList("ImageAssets")?.GetRawValue().OfType<string>();
99 bool includeImagePatternImages = Model.Item.GetBoolean("ImagePatternImages");
100
101
102 Dynamicweb.Ecommerce.Products.ProductService ps = new Dynamicweb.Ecommerce.Products.ProductService();
103 Dynamicweb.Ecommerce.Products.DetailsGroupService dgs = new Dynamicweb.Ecommerce.Products.DetailsGroupService();
104
105 List<ewiMediaViewModel> productAssets = new List<ewiMediaViewModel>();
106 List<Dynamicweb.Ecommerce.Products.Product> products = new List<Dynamicweb.Ecommerce.Products.Product>();
107 foreach (var language in ecomLanguages)
108 {
109 var productitem = ps.GetProductById(product.Id, product.VariantId, language.LanguageId);
110 if (productitem is object)
111 {
112 Dynamicweb.Ecommerce.Products.DetailService detailService = new Dynamicweb.Ecommerce.Products.DetailService();
113
114 foreach (var detail in detailService.GetDetails(productitem))
115 {
116 if (detail.LanguageId == language.LanguageId)
117 {
118 Dynamicweb.Ecommerce.Products.DetailsGroup detailsGroup = dgs.GetById(detail.GroupId);
119
120 if (selectedAssetCategories.Contains(detailsGroup.SystemName))
121 {
122 // Check if this language is already in activeLanguages before adding
123 if (!activeLanguages.Any(al => al.LanguageId == language.LanguageId))
124 {
125 activeLanguages.Add(language);
126 }
127
128 ewiMediaViewModel productAsset = new ewiMediaViewModel();
129 productAsset.Value = detail.Value;
130 productAsset.AssetSystemName = detailsGroup.SystemName;
131 productAsset.LanguageId = detail.LanguageId;
132 productAsset.LanguageName = language.NativeName;
133 productAsset.DisplayName = detail.Name;
134 productAssets.Add(productAsset);
135 }
136 }
137 }
138 }
139 }
140
141
142
143 string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : "";
144 IEnumerable<MediaViewModel> assetsImages = selectedAssetCategories != null ?
145 product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets) :
146 product.AssetCategories.SelectMany(x => x.Assets);
147 assetsImages = assetsImages.OrderByDescending(x => x.Value.Equals(defaultImage));
148 IEnumerable<MediaViewModel> assetsList = new MediaViewModel[] { };
149 assetsList = productAssets.Cast<MediaViewModel>();
150 assetsList = includeImagePatternImages ? assetsList.Union(product.ImagePatternImages) : assetsList;
151 assetsList = includeImagePatternImages && assetsList.Count() == 0 ? assetsList.Append(product.DefaultImage) : assetsList;
152 bool defaultImageFallback = Model.Item.GetBoolean("DefaultImageFallback");
153 bool showOnlyPrimaryImage = Model.Item.GetBoolean("ShowOnlyPrimaryImage");
154 int totalAssets = 0;
155 if (showOnlyPrimaryImage == false) {
156 foreach (MediaViewModel asset in assetsList) {
157 var assetValue = asset.Value;
158 foreach (string format in allSupportedFormats) {
159 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) {
160 totalAssets++;
161 }
162 }
163 }
164 }
165 if ((totalAssets == 0 && product.DefaultImage != null && selectedAssetCategories?.Count() == 0) || (showOnlyPrimaryImage == true && product.DefaultImage != null))
166 {
167 assetsList = new List<MediaViewModel>(){ product.DefaultImage };
168 totalAssets = 1;
169 }
170 int videoNumber = 0;
171
172 string spacing = Model.Item.GetRawValueString("Spacing", "p-0");
173 spacing = spacing == "none" ? "p-0" : spacing;
174 spacing = spacing == "small" ? "p-3" : spacing;
175 spacing = spacing == "large" ? "p-5" : spacing;
176 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
177 bool hideThumbnails = Model.Item.GetBoolean("HideThumbnails");
178 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/";
179 int modalVideoNumber = 0;
180
181 if (totalAssets != 0 && assetsList.Any())
182 {
183 WriteLiteral(" <div");
184 BeginWriteAttribute("class", " class=\"", 11709, "\"", 11771, 4);
185 WriteAttributeValue("", 11717, spacing, 11717, 8, false);
186 WriteAttributeValue("", 11725, theme, 11725, 8, false);
187 WriteAttributeValue(" ", 11733, "item_", 11734, 6, true);
188 WriteAttributeValue("", 11739, Model.Item.SystemName.ToLower(), 11739, 32, false);
189 EndWriteAttribute();
190 WriteLiteral(">\r\n");
191 if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle"))
192 {
193 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h3");
194 WriteLiteral(" <h3");
195 BeginWriteAttribute("class", " class=\"", 12013, "\"", 12040, 2);
196 WriteAttributeValue("", 12021, titleFontSize, 12021, 14, false);
197 WriteAttributeValue(" ", 12035, "mb-3", 12036, 5, true);
198 EndWriteAttribute();
199 WriteLiteral(">\r\n ");
200 Write(Model.Item.GetString("Title"));
201 WriteLiteral("\r\n </h3>\r\n");
202 }
203 if (activeLanguages.Count > 1)
204 {
205
206 // Filter activeLanguages als deze taal assets bevat
207 var languagesWithAssets = new List<Dynamicweb.Ecommerce.International.Language>();
208
209 foreach (var lang in activeLanguages)
210 {
211 bool hasAssets = false;
212 foreach (MediaViewModel asset in assetsList)
213 {
214 try {
215 if (asset.GetType().GetProperty("LanguageId") != null)
216 {
217 var assetLangId = asset.GetType().GetProperty("LanguageId").GetValue(asset)?.ToString() ?? "";
218 if (assetLangId == lang.LanguageId)
219 {
220 hasAssets = true;
221 break;
222 }
223 }
224 } catch { }
225 }
226
227 if (hasAssets)
228 {
229 languagesWithAssets.Add(lang);
230 }
231 }
232
233 Dynamicweb.Ecommerce.International.Language currentLanguage = null;
234 string currentLanguageValue = "ALL";
235
236 // Toon enkel de taal dropdown als er meer dan 1 taal is met assets
237 if (languagesWithAssets.Count > 1)
238 {
239
240 currentLanguage = languagesWithAssets.FirstOrDefault(lang =>
241 string.Equals(lang.Culture, siteLanguage, StringComparison.OrdinalIgnoreCase)) ??
242 languagesWithAssets.FirstOrDefault(lang =>
243 string.Equals(lang.NativeName, "English", StringComparison.OrdinalIgnoreCase)) ??
244 languagesWithAssets.FirstOrDefault();
245
246 // Map English naar LANG1
247 currentLanguageValue = currentLanguage != null &&
248 string.Equals(currentLanguage.NativeName, "English", StringComparison.OrdinalIgnoreCase)
249 ? "LANG1" : currentLanguage?.LanguageId ?? "ALL";
250 }
251 if (languagesWithAssets.Count > 1)
252 {
253 WriteLiteral(" <div class=\"mb-3\">\r\n <div class=\"mb-1\">");
254 Write(Translate("Language"));
255 WriteLiteral(@"</div>
256 <div class=""dropdown js-dropdown"">
257 <button class=""form-select text-start w-100 js-dropdown-btn"" type=""button"" data-bs-toggle=""dropdown"" data-bs-auto-close=""outside"" aria-expanded=""false"">
258 ");
259 Write(currentLanguage?.NativeName ?? "All");
260 WriteLiteral(@"
261 </button>
262 <div class=""dropdown-menu w-100 p-3"">
263 <div class=""form-check"">
264 <input class=""form-check-input"" type=""checkbox"" name=""LanguageId"" value=""ALL"" id=""LanguageCheckAll"" onchange=""filterResults('ALL', event);"">
265 <label class=""form-check-label"" for=""LanguageCheckAll"">
266 ");
267 Write(Translate("All"));
268 WriteLiteral("\r\n </label>\r\n </div>\r\n");
269 foreach (var language in languagesWithAssets.GroupBy(l => l.NativeName).Select(g => g.First()))
270 {
271 string languageValue = string.Equals(language.NativeName, "English", StringComparison.OrdinalIgnoreCase)
272 ? "LANG1" : language.LanguageId;
273 bool isCurrentLanguage = language == currentLanguage;
274 WriteLiteral(" <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" name=\"LanguageId\" data-short-name=\"");
275 Write(language.NativeName);
276 WriteLiteral("\"");
277 BeginWriteAttribute("value", " value=\"", 16500, "\"", 16522, 1);
278 WriteAttributeValue("", 16508, languageValue, 16508, 14, false);
279 EndWriteAttribute();
280 BeginWriteAttribute("id", " id=\"", 16523, "\"", 16548, 2);
281 WriteAttributeValue("", 16528, "Check_", 16528, 6, true);
282 WriteAttributeValue("", 16534, languageValue, 16534, 14, false);
283 EndWriteAttribute();
284 WriteLiteral(" ");
285 Write(isCurrentLanguage ? "checked" : "");
286 WriteLiteral(" onchange=\"filterResults(\'");
287 Write(languageValue);
288 WriteLiteral("\', event);\">\r\n <label class=\"form-check-label\"");
289 BeginWriteAttribute("for", " for=\"", 16712, "\"", 16738, 2);
290 WriteAttributeValue("", 16718, "Check_", 16718, 6, true);
291 WriteAttributeValue("", 16724, languageValue, 16724, 14, false);
292 EndWriteAttribute();
293 WriteLiteral(">\r\n ");
294 Write(language.NativeName);
295 WriteLiteral("\r\n </label>\r\n </div>\r\n");
296 }
297 WriteLiteral(" </div>\r\n </div>\r\n </div>\r\n");
298 }
299 }
300 WriteLiteral(" <div class=\"table-responsive\">\r\n <table class=\"table table-hover align-middle mb-0\" style=\"table-layout: fixed;\" id=\"assets-table\">\r\n <thead>\r\n <tr>\r\n");
301 if (!hideThumbnails)
302 {
303 WriteLiteral(" <th style=\"width:60px\"> </th>\r\n");
304 }
305 WriteLiteral(" <th>");
306 Write(Translate("Name"));
307 WriteLiteral("</th>\r\n <th>");
308 Write(Translate("Asset type"));
309 WriteLiteral("</th>\r\n <th>");
310 Write(Translate("Language"));
311 WriteLiteral("</th>\r\n <th class=\"text-end\" style=\"width:100px\">");
312 Write(Translate("File type"));
313 WriteLiteral("</th>\r\n <th class=\"text-end d-none d-lg-table-cell\">");
314 Write(Translate("Download"));
315 WriteLiteral("</th>\r\n </tr>\r\n </thead>\r\n <tbody class=\"border-top-0\">\r\n");
316 foreach (ewiMediaViewModel asset in productAssets)
317 {
318 var assetValue = asset.Value;
319 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Value.Substring(asset.Value.LastIndexOf('/') + 1);
320
321 bool isVideo = false;
322
323 foreach (string format in supportedVideoFormats)
324 { //Videos
325 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0)
326 {
327 isVideo = true;
328 }
329 }
330 // Check if it's a supported format
331 if (!isVideo)
332 {
333 // Get file extension for file type display
334 string filePath = Dynamicweb.Context.Current.Server.MapPath(assetValue);
335 long fileSize = 0;
336 if (File.Exists(filePath))
337 {
338 fileSize = new System.IO.FileInfo(filePath) != null ? new System.IO.FileInfo(filePath).Length / 1024 : 0;
339
340 foreach (string format in allSupportedFormats)
341 {
342 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0)
343 {
344 string show = "hide-row";
345 WriteLiteral("\t\t\t\t\t\t\t\t\t\t\t<tr");
346 BeginWriteAttribute("class", " class=\"", 19370, "\"", 19401, 2);
347 WriteAttributeValue("", 19378, asset.LanguageId, 19378, 17, false);
348 WriteAttributeValue(" ", 19395, show, 19396, 5, false);
349 EndWriteAttribute();
350 WriteLiteral(">\r\n");
351 if (!hideThumbnails)
352 {
353 Write(RenderAsset(asset));
354
355 }
356 WriteLiteral(" string languageId = string.Equals(asset.LanguageName, \"English\", StringComparison.OrdinalIgnoreCase) ? \"LANG1\" : asset.LanguageId;\r\n \r\n <tr data-language-ids=\"");
357 Write(languageId);
358 WriteLiteral("\" data-language-name=\"");
359 Write(asset.LanguageName);
360 WriteLiteral("\">\r\n");
361 if (!hideThumbnails)
362 {
363 WriteLiteral(" <td class=\"px-0\">\r\n");
364
365 string productName = product.Name;
366 string imagePath = asset.Value;
367 string imageLinkPath = imagePath;
368 imagePath = $"/Admin/Public/GetImage.ashx?image={imagePath}&width=60&format=webp";
369 RatioSettings ratioSettings = GetRatioSettings();
370 WriteLiteral(" <a");
371 BeginWriteAttribute("href", " href=\"", 20590, "\"", 20611, 1);
372 WriteAttributeValue("", 20597, imageLinkPath, 20597, 14, false);
373 EndWriteAttribute();
374 BeginWriteAttribute("class", " class=\"", 20612, "\"", 20674, 3);
375 WriteAttributeValue("", 20620, "d-block", 20620, 7, true);
376 WriteAttributeValue(" ", 20627, ratioSettings.CssClass, 20628, 25, false);
377 WriteAttributeValue("", 20653, ratioSettings.Fill, 20653, 21, false);
378 EndWriteAttribute();
379 BeginWriteAttribute("style", " style=\"", 20675, "\"", 20711, 1);
380 WriteAttributeValue("", 20683, ratioSettings.CssVariable, 20683, 28, false);
381 EndWriteAttribute();
382 WriteLiteral(" download");
383 BeginWriteAttribute("alt", " alt=\"", 20721, "\"", 20739, 1);
384 WriteAttributeValue("", 20727, productName, 20727, 12, false);
385 EndWriteAttribute();
386 WriteLiteral(">\r\n <div class=\"d-flex align-items-center justify-content-center overflow-hidden h-100\">\r\n <img loading=\"lazy\"");
387 BeginWriteAttribute("src", " src=\"", 20948, "\"", 20964, 1);
388 WriteAttributeValue("", 20954, imagePath, 20954, 10, false);
389 EndWriteAttribute();
390 WriteLiteral(" class=\"mw-100 mh-100\"");
391 BeginWriteAttribute("alt", " alt=\"", 20987, "\"", 21005, 1);
392 WriteAttributeValue("", 20993, productName, 20993, 12, false);
393 EndWriteAttribute();
394 WriteLiteral(" />\r\n </div>\r\n </a>\r\n </td>\r\n");
395 }
396 WriteLiteral(" <td><span class=\"hide-on-desktop\">");
397 Write(Translate("Name"));
398 WriteLiteral("</span> <span>");
399 Write(assetName);
400 WriteLiteral("</span></td>\r\n\t\t\t\t\t\t\t\t\t<td><span class=\"hide-on-desktop\">");
401 Write(Translate("Asset type"));
402 WriteLiteral("</span> <span>");
403 Write(asset.AssetSystemName);
404 WriteLiteral("</span></td>\r\n <td><span class=\"hide-on-desktop\">");
405 Write(Translate("Language"));
406 WriteLiteral("</span> <span>");
407 Write(asset.LanguageName);
408 WriteLiteral("</span></td>\r\n\t\t\t\t\t\t\t\t\t<td class=\"no-border-bottom\"><span class=\"hide-on-desktop\">");
409 Write(Translate("File type"));
410 WriteLiteral("</span> <span>.pdf</span></td>\r\n <td class=\"text-end\">\r\n\t\t\t\t\t\t\t\t\t\t<a");
411 BeginWriteAttribute("href", " href=\"", 21779, "\"", 21797, 1);
412 WriteAttributeValue("", 21786, assetValue, 21786, 11, false);
413 EndWriteAttribute();
414 WriteLiteral(" class=\"download-button\" target=\"_blank\">");
415 Write(Translate("Download"));
416 WriteLiteral(@"</a>
417 </td>
418 </tr>
419 }
420 }
421 </tbody>
422 </table>
423 </div>
424 <script>
425 function filterResults(selectedLang, event) {
426 console.log('Filtering by language:', selectedLang);
427
428 // Prevent event bubbling
429 if (event) {
430 event.stopPropagation();
431 }
432
433 const table = document.getElementById('assets-table');
434 const rows = table.querySelectorAll('tbody tr');
435 const button = document.querySelector('.js-dropdown-btn');
436
437 const checkedBoxes = document.querySelectorAll('input[name=""LanguageId""]:checked');
438 const checkedLanguages = Array.from(checkedBoxes).map(cb => cb.value);
439
440 ");
441 WriteLiteral(@" // Handle ""All"" checkbox behavior - if ""All"" is checked, uncheck others
442 if (selectedLang === 'ALL') {
443 const allCheckbox = document.querySelector('input[value=""ALL""]');
444 if (allCheckbox && allCheckbox.checked) {
445 // Uncheck all other checkboxes
446 document.querySelectorAll('input[name=""LanguageId""]:not([value=""ALL""])').forEach(cb => {
447 cb.checked = false;
448 });
449 }
450 } else {
451 // If any specific language is checked, uncheck ""All""
452 const allCheckbox = document.querySelector('input[value=""ALL""]');
453 if (allCheckbox) {
454 allCheckbox.checked = false;
455 }
456 }
457
458 // Re-get checked languages after potenti");
459 WriteLiteral(@"al changes
460 const finalCheckedBoxes = document.querySelectorAll('input[name=""LanguageId""]:checked');
461 const finalCheckedLanguages = Array.from(finalCheckedBoxes).map(cb => cb.value);
462
463 // Update button text based on selected languages
464 if (finalCheckedLanguages.length === 0) {
465 button.textContent = '");
466 Write(Translate("All"));
467 WriteLiteral("\';\r\n } else if (finalCheckedLanguages.includes(\'ALL\')) {\r\n button.textContent = \'");
468 Write(Translate("All"));
469 WriteLiteral(@"';
470 } else if (finalCheckedLanguages.length === 1) {
471 const selectedCheckbox = document.querySelector(`input[value=""${finalCheckedLanguages[0]}""]`);
472 button.textContent = selectedCheckbox ? selectedCheckbox.getAttribute('data-short-name') : 'All';
473 } else {
474 button.textContent = `${finalCheckedLanguages.length} languages selected`;
475 }
476
477 // Filter table rows
478 rows.forEach(row => {
479 const rowLanguageIds = row.getAttribute('data-language-ids');
480 const rowLanguageName = row.getAttribute('data-language-name');
481
482 if (finalCheckedLanguages.length === 0 || finalCheckedLanguages.includes('ALL')) {
483 row.style.display = '';
484 } else {
485 const shouldShow = ro");
486 WriteLiteral(@"wLanguageIds && finalCheckedLanguages.some(lang =>
487 rowLanguageIds === lang ||
488 rowLanguageIds === 'ALL'
489 );
490
491 row.style.display = shouldShow ? '' : 'none';
492 }
493 });
494
495 }
496 document.addEventListener('DOMContentLoaded', function() {
497 // Set initial state - apply filter for pre-checked language
498 const currentLangCheckbox = document.querySelector('input[name=""LanguageId""]:checked');
499 if (currentLangCheckbox) {
500 filterResults(currentLangCheckbox.value);
501 } else {
502 // Default to show all if nothing is checked
503 const table = document.getElementById('assets-table');
504 const rows = table.querySelectorAll('tbody tr');
");
505 WriteLiteral("\n rows.forEach(row => {\r\n row.style.display = \'\';\r\n });\r\n }\r\n });\r\n </script>\r\n");
506 foreach (MediaViewModel asset in assetsList)
507 {
508 var assetName = asset.Value.ToLower();
509 foreach (string videoFormat in supportedVideoFormats)
510 { //Videos
511 if (assetName.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0)
512 {
513 WriteLiteral(" <div class=\"modal fade js-video-modal\"");
514 BeginWriteAttribute("id", " id=\"", 27149, "\"", 27189, 4);
515 WriteAttributeValue("", 27154, "modal_", 27154, 6, true);
516 WriteAttributeValue("", 27160, Model.ID, 27160, 11, false);
517 WriteAttributeValue("", 27171, "_", 27171, 1, true);
518 WriteAttributeValue("", 27172, modalVideoNumber, 27172, 17, false);
519 EndWriteAttribute();
520 WriteLiteral(" tabindex=\"-1\"");
521 BeginWriteAttribute("aria-labelledby", " aria-labelledby=\"", 27204, "\"", 27281, 4);
522 WriteAttributeValue("", 27222, "productDetailsTableModalTitle_", 27222, 30, true);
523 WriteAttributeValue("", 27252, Model.ID, 27252, 11, false);
524 WriteAttributeValue("", 27263, "_", 27263, 1, true);
525 WriteAttributeValue("", 27264, modalVideoNumber, 27264, 17, false);
526 EndWriteAttribute();
527 WriteLiteral(@" aria-hidden=""true"">
528 <div class=""modal-dialog modal-dialog-centered modal-xl"">
529 <div class=""modal-content"">
530 <div class=""modal-header visually-hidden"">
531 <h5 class=""modal-title""");
532 BeginWriteAttribute("id", " id=\"", 27595, "\"", 27659, 4);
533 WriteAttributeValue("", 27600, "productDetailsTableModalTitle_", 27600, 30, true);
534 WriteAttributeValue("", 27630, Model.ID, 27630, 11, false);
535 WriteAttributeValue("", 27641, "_", 27641, 1, true);
536 WriteAttributeValue("", 27642, modalVideoNumber, 27642, 17, false);
537 EndWriteAttribute();
538 WriteLiteral(">");
539 Write(product.Title);
540 WriteLiteral(@"</h5>
541 <button type=""button"" class=""btn-close"" data-bs-dismiss=""modal"" aria-label=""Close""></button>
542 </div>
543 <div class=""modal-body p-2 p-lg-3 h-100"">
544 ");
545
546 var videoParams = GetVideoParams(asset, "modal");
547 Write(RenderPartial("Components/VideoPlayer.cshtml", new Dynamicweb.Frontend.FileViewModel { Path = asset.Value }, videoParams));
548 WriteLiteral(" </div>\r\n </div>\r\n </div>\r\n </div>\r\n");
549 modalVideoNumber++;
550 }
551 }
552 }WriteLiteral(" </div>\r\n");
553 }
554 else if (Pageview.IsVisualEditorMode)
555 {
556 WriteLiteral(" <div");
557 BeginWriteAttribute("class", " class=\"", 28629, "\"", 28649, 2);
558 WriteAttributeValue("", 28637, "h-100", 28637, 5, true);
559 WriteAttributeValue(" ", 28642, theme, 28643, 6, false);
560 EndWriteAttribute();
561 WriteLiteral(">\r\n <div class=\"alert alert-dark m-0\">\r\n ");
562 Write(Translate("No assets are available"));
563 WriteLiteral("\r\n </div>\r\n </div>\r\n");
564 }
565 }
566 }
567 #pragma warning restore 1998
568
569 public ProductViewModel product { get; set; } = new ProductViewModel();
570 public string[] supportedImageFormats { get; set; }
571 public string[] supportedVideoFormats { get; set; }
572 public string[] supportedDocumentFormats { get; set; }
573 public string[] allSupportedFormats { get; set; }
574 public class RatioSettings
575 {
576 public string Ratio { get; set; }
577 public string CssClass { get; set; }
578 public string CssVariable { get; set; }
579 public string Fill { get; set; }
580 }
581 public RatioSettings GetRatioSettings()
582 {
583 var ratioSettings = new RatioSettings();
584 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", "");
585 ratio = ratio != "0" ? ratio : "";
586 string cssClass = ratio != "" && ratio != "fill" ? " ratio" : "";
587 string cssVariable = ratio != "" && ratio != "fill" ? "--bs-aspect-ratio: " + ratio : "";
588 ratioSettings.Ratio = ratio;
589 ratioSettings.CssClass = cssClass;
590 ratioSettings.CssVariable = cssVariable;
591 ratioSettings.Fill = ratio == "fill" ? " h-100" : "";
592 return ratioSettings;
593 }
594 // PDB: eWings MediaViewModel extender
595 public class ewiMediaViewModel : MediaViewModel
596 {
597 public string LanguageId { get; set; }
598 public string LanguageName { get; set; }
599 public string AssetSystemName { get; set; }
600 }
601 public Dictionary<string, object> GetVideoParams(MediaViewModel asset, string size)
602 {
603 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Name;
604 string type = GetVideoType(asset.Value);
605 bool openInModal = Model.Item.GetString("OpenVideoInModal") == "true" ? true : false;
606 bool autoPlay = Model.Item.GetBoolean("VideoAutoPlay");
607 var videoParams = new Dictionary<string, object>();
608 videoParams.Add("AssetName", asset.Name);
609 videoParams.Add("AssetVideoType", type);
610 videoParams.Add("AssetDisplayName", asset.DisplayName);
611 videoParams.Add("OpenVideoInModal", openInModal);
612 videoParams.Add("VideoAutoPlay", autoPlay);
613 videoParams.Add("Size", size);
614 videoParams.Add("Id", Model.ID);
615 return videoParams;
616 }
617 public string GetVideoType(string assetValue)
618 {
619 string type = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "youtube" : string.Empty;
620 type = assetValue.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "vimeo" : type;
621 type = string.IsNullOrEmpty(type) ? "selfhosted" : type;
622 return type;
623 }
624 public string GetYoutubeScreenDump(string assetValue)
625 {
626 var regex = new Regex(@"(?:youtube\.com\/.*[\?&]v=|youtu\.be\/|youtube\.com\/embed\/)([\w-]+)(?:\?.*)?");
627 Match match = regex.Match(assetValue);
628 string videoId = match.Success ? match.Groups[1].Value : string.Empty;
629 string youtubeThumbnail = $"https://img.youtube.com/vi/{videoId}/mqdefault.jpg";
630 return youtubeThumbnail;
631 }
632 }
633 }
634 #pragma warning restore 1591
635
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel>
2 @using Dynamicweb.Ecommerce.ProductCatalog
3 @using System.Text.RegularExpressions;
4 @using System.IO
5 @functions {
6 public ProductViewModel product { get; set; } = new ProductViewModel();
7 public string[] supportedImageFormats { get; set; }
8 public string[] supportedVideoFormats { get; set; }
9 public string[] supportedDocumentFormats { get; set; }
10 public string[] allSupportedFormats { get; set; }
11 public class RatioSettings
12 {
13 public string Ratio { get; set; }
14 public string CssClass { get; set; }
15 public string CssVariable { get; set; }
16 public string Fill { get; set; }
17 }
18 public RatioSettings GetRatioSettings()
19 {
20 var ratioSettings = new RatioSettings();
21 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", "");
22 ratio = ratio != "0" ? ratio : "";
23 string cssClass = ratio != "" && ratio != "fill" ? " ratio" : "";
24 string cssVariable = ratio != "" && ratio != "fill" ? "--bs-aspect-ratio: " + ratio : "";
25 ratioSettings.Ratio = ratio;
26 ratioSettings.CssClass = cssClass;
27 ratioSettings.CssVariable = cssVariable;
28 ratioSettings.Fill = ratio == "fill" ? " h-100" : "";
29 return ratioSettings;
30 }
31 // PDB: eWings MediaViewModel extender
32 public class ewiMediaViewModel : MediaViewModel
33 {
34 public string LanguageId { get; set; }
35 public string LanguageName { get; set; }
36 public string AssetSystemName { get; set; }
37 }
38 public Dictionary<string, object> GetVideoParams(MediaViewModel asset, string size)
39 {
40 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Name;
41 string type = GetVideoType(asset.Value);
42 bool openInModal = Model.Item.GetString("OpenVideoInModal") == "true" ? true : false;
43 bool autoPlay = Model.Item.GetBoolean("VideoAutoPlay");
44 var videoParams = new Dictionary<string, object>();
45 videoParams.Add("AssetName", asset.Name);
46 videoParams.Add("AssetVideoType", type);
47 videoParams.Add("AssetDisplayName", asset.DisplayName);
48 videoParams.Add("OpenVideoInModal", openInModal);
49 videoParams.Add("VideoAutoPlay", autoPlay);
50 videoParams.Add("Size", size);
51 videoParams.Add("Id", Model.ID);
52 return videoParams;
53 }
54 public string GetVideoType(string assetValue)
55 {
56 string type = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "youtube" : string.Empty;
57 type = assetValue.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "vimeo" : type;
58 type = string.IsNullOrEmpty(type) ? "selfhosted" : type;
59 return type;
60 }
61 public string GetYoutubeScreenDump(string assetValue)
62 {
63 var regex = new Regex(@"(?:youtube\.com\/.*[\?&]v=|youtu\.be\/|youtube\.com\/embed\/)([\w-]+)(?:\?.*)?");
64 Match match = regex.Match(assetValue);
65 string videoId = match.Success ? match.Groups[1].Value : string.Empty;
66 string youtubeThumbnail = $"https://img.youtube.com/vi/{videoId}/mqdefault.jpg";
67 return youtubeThumbnail;
68 }
69 }
70 @{
71 @* Get the product data *@
72 ProductViewModel product = null;
73 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
74 {
75 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
76 }
77 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode)
78 {
79 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page);
80 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel();
81 if (productList?.Products is object)
82 {
83 product = productList.Products[0];
84 }
85 }
86 string siteLanguage = Pageview.Area.CultureInfo.Name;
87
88 @* Get active website languages first *@
89 int pageId = Dynamicweb.Context.Current.Request["CurrentPageID"] != null ? Convert.ToInt32(Dynamicweb.Context.Current.Request["CurrentPageID"]) : Pageview.ID;
90 var currentPage = Dynamicweb.Content.Services.Pages.GetPage(pageId);
91 List<Dynamicweb.Content.Page> websiteLanguages = new List<Dynamicweb.Content.Page>();
92 if (currentPage.Area.IsMaster)
93 {
94 websiteLanguages.Add(currentPage); // Add master language
95 if (currentPage.Languages != null)
96 {
97 foreach (var lang in currentPage.Languages)
98 {
99 if (lang.Area.Active == true) // Filter active languages
100 {
101 websiteLanguages.Add(lang);
102 }
103 }
104 }
105 }
106 else
107 {
108 websiteLanguages.Add(currentPage.MasterPage); // Add master page
109 if (currentPage.MasterPage != null && currentPage.MasterPage.Languages != null)
110 {
111 foreach (var lang in currentPage.MasterPage.Languages)
112 {
113 if (lang.Area.Active == true)
114 {
115 websiteLanguages.Add(lang);
116 }
117 }
118 }
119 }
120
121 @* Get ecommerce languages and filter by active website languages *@
122 var ecomLanguages = Dynamicweb.Ecommerce.Services.Languages.GetLanguages();
123 List<Dynamicweb.Ecommerce.International.Language> activeLanguages = new List<Dynamicweb.Ecommerce.International.Language>();
124
125 @* Filter ecommerce languages to only include those corresponding to active website languages *@
126 foreach (var websiteLanguage in websiteLanguages)
127 {
128 var matchingEcomLanguage = ecomLanguages.FirstOrDefault(ecomLang =>
129 string.Equals(ecomLang.Culture, websiteLanguage.Area.CultureInfo.Name, StringComparison.OrdinalIgnoreCase) ||
130 string.Equals(ecomLang.Code, websiteLanguage.Area.CultureInfo.TwoLetterISOLanguageName, StringComparison.OrdinalIgnoreCase));
131
132 if (matchingEcomLanguage != null && !activeLanguages.Contains(matchingEcomLanguage))
133 {
134 activeLanguages.Add(matchingEcomLanguage);
135 }
136 }
137 @* Fallback: if no matches found, use all ecommerce languages *@
138 if (activeLanguages.Count == 0)
139 {
140 activeLanguages = ecomLanguages.ToList();
141 }
142 }
143 @if (product is object)
144 {
145 @* Supported formats *@
146 supportedImageFormats = new string[] { ".jpg", ".jpeg", ".webp", ".png", ".gif", ".bmp", ".tiff" };
147 supportedVideoFormats = new string[] { "youtu.be", "youtube", "vimeo", ".mp4", ".webm" };
148 supportedDocumentFormats = new string[] { ".pdf", ".docx", ".xlsx", ".ppt", ".pptx", ".igs", ".ipt", ".sat", ".stp", ".dwg", ".dxf", ".dwf" };
149 allSupportedFormats = supportedImageFormats.Concat(supportedVideoFormats).Concat(supportedDocumentFormats).ToArray();
150
151 @* Collect the assets *@
152 var selectedAssetCategories = Model.Item.GetList("ImageAssets")?.GetRawValue().OfType<string>();
153 bool includeImagePatternImages = Model.Item.GetBoolean("ImagePatternImages");
154
155 @* PDB: Collect the valid assets and languages *@
156 Dynamicweb.Ecommerce.Products.ProductService ps = new Dynamicweb.Ecommerce.Products.ProductService();
157 Dynamicweb.Ecommerce.Products.DetailsGroupService dgs = new Dynamicweb.Ecommerce.Products.DetailsGroupService();
158
159 List<ewiMediaViewModel> productAssets = new List<ewiMediaViewModel>();
160 List<Dynamicweb.Ecommerce.Products.Product> products = new List<Dynamicweb.Ecommerce.Products.Product>();
161 foreach (var language in ecomLanguages)
162 {
163 var productitem = ps.GetProductById(product.Id, product.VariantId, language.LanguageId);
164 if (productitem is object)
165 {
166 Dynamicweb.Ecommerce.Products.DetailService detailService = new Dynamicweb.Ecommerce.Products.DetailService();
167
168 foreach (var detail in detailService.GetDetails(productitem))
169 {
170 if (detail.LanguageId == language.LanguageId)
171 {
172 Dynamicweb.Ecommerce.Products.DetailsGroup detailsGroup = dgs.GetById(detail.GroupId);
173
174 if (selectedAssetCategories.Contains(detailsGroup.SystemName))
175 {
176 // Check if this language is already in activeLanguages before adding
177 if (!activeLanguages.Any(al => al.LanguageId == language.LanguageId))
178 {
179 activeLanguages.Add(language);
180 }
181
182 ewiMediaViewModel productAsset = new ewiMediaViewModel();
183 productAsset.Value = detail.Value;
184 productAsset.AssetSystemName = detailsGroup.SystemName;
185 productAsset.LanguageId = detail.LanguageId;
186 productAsset.LanguageName = language.NativeName;
187 productAsset.DisplayName = detail.Name;
188 productAssets.Add(productAsset);
189 }
190 }
191 }
192 }
193 }
194
195
196 @* Standard asset collection (existing logic) *@
197 string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : "";
198 IEnumerable<MediaViewModel> assetsImages = selectedAssetCategories != null ?
199 product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets) :
200 product.AssetCategories.SelectMany(x => x.Assets);
201 assetsImages = assetsImages.OrderByDescending(x => x.Value.Equals(defaultImage));
202 IEnumerable<MediaViewModel> assetsList = new MediaViewModel[] { };
203 assetsList = productAssets.Cast<MediaViewModel>();
204 assetsList = includeImagePatternImages ? assetsList.Union(product.ImagePatternImages) : assetsList;
205 assetsList = includeImagePatternImages && assetsList.Count() == 0 ? assetsList.Append(product.DefaultImage) : assetsList;
206 bool defaultImageFallback = Model.Item.GetBoolean("DefaultImageFallback");
207 bool showOnlyPrimaryImage = Model.Item.GetBoolean("ShowOnlyPrimaryImage");
208 int totalAssets = 0;
209 if (showOnlyPrimaryImage == false) {
210 foreach (MediaViewModel asset in assetsList) {
211 var assetValue = asset.Value;
212 foreach (string format in allSupportedFormats) {
213 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) {
214 totalAssets++;
215 }
216 }
217 }
218 }
219 if ((totalAssets == 0 && product.DefaultImage != null && selectedAssetCategories?.Count() == 0) || (showOnlyPrimaryImage == true && product.DefaultImage != null))
220 {
221 assetsList = new List<MediaViewModel>(){ product.DefaultImage };
222 totalAssets = 1;
223 }
224 int videoNumber = 0;
225 @* Layout settings *@
226 string spacing = Model.Item.GetRawValueString("Spacing", "p-0");
227 spacing = spacing == "none" ? "p-0" : spacing;
228 spacing = spacing == "small" ? "p-3" : spacing;
229 spacing = spacing == "large" ? "p-5" : spacing;
230 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
231 bool hideThumbnails = Model.Item.GetBoolean("HideThumbnails");
232 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/";
233 int modalVideoNumber = 0;
234 @* Get assets from selected categories or get all assets *@
235 if (totalAssets != 0 && assetsList.Any())
236 {
237 <div class="@spacing@(theme) item_@Model.Item.SystemName.ToLower()">
238 @if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle"))
239 {
240 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h3");
241 <h3 class="@titleFontSize mb-3">
242 @Model.Item.GetString("Title")
243 </h3>
244 }
245 @if (activeLanguages.Count > 1)
246 {
247 @{
248 // Filter activeLanguages als deze taal assets bevat
249 var languagesWithAssets = new List<Dynamicweb.Ecommerce.International.Language>();
250
251 foreach (var lang in activeLanguages)
252 {
253 bool hasAssets = false;
254 foreach (MediaViewModel asset in assetsList)
255 {
256 try {
257 if (asset.GetType().GetProperty("LanguageId") != null)
258 {
259 var assetLangId = asset.GetType().GetProperty("LanguageId").GetValue(asset)?.ToString() ?? "";
260 if (assetLangId == lang.LanguageId)
261 {
262 hasAssets = true;
263 break;
264 }
265 }
266 } catch { }
267 }
268
269 if (hasAssets)
270 {
271 languagesWithAssets.Add(lang);
272 }
273 }
274
275 Dynamicweb.Ecommerce.International.Language currentLanguage = null;
276 string currentLanguageValue = "ALL";
277
278 // Toon enkel de taal dropdown als er meer dan 1 taal is met assets
279 if (languagesWithAssets.Count > 1)
280 {
281
282 currentLanguage = languagesWithAssets.FirstOrDefault(lang =>
283 string.Equals(lang.Culture, siteLanguage, StringComparison.OrdinalIgnoreCase)) ??
284 languagesWithAssets.FirstOrDefault(lang =>
285 string.Equals(lang.NativeName, "English", StringComparison.OrdinalIgnoreCase)) ??
286 languagesWithAssets.FirstOrDefault();
287
288 // Map English naar LANG1
289 currentLanguageValue = currentLanguage != null &&
290 string.Equals(currentLanguage.NativeName, "English", StringComparison.OrdinalIgnoreCase)
291 ? "LANG1" : currentLanguage?.LanguageId ?? "ALL";
292 }
293 }
294
295 @if (languagesWithAssets.Count > 1)
296 {
297 <div class="mb-3">
298 <div class="mb-1">@Translate("Language")</div>
299 <div class="dropdown js-dropdown">
300 <button class="form-select text-start w-100 js-dropdown-btn" type="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
301 @(currentLanguage?.NativeName ?? "All")
302 </button>
303 <div class="dropdown-menu w-100 p-3">
304 <div class="form-check">
305 <input class="form-check-input" type="checkbox" name="LanguageId" value="ALL" id="LanguageCheckAll" onchange="filterResults('ALL', event);">
306 <label class="form-check-label" for="LanguageCheckAll">
307 @Translate("All")
308 </label>
309 </div>
310 @foreach (var language in languagesWithAssets.GroupBy(l => l.NativeName).Select(g => g.First()))
311 {
312 string languageValue = string.Equals(language.NativeName, "English", StringComparison.OrdinalIgnoreCase)
313 ? "LANG1" : language.LanguageId;
314 bool isCurrentLanguage = language == currentLanguage;
315 <div class="form-check">
316 <input class="form-check-input" type="checkbox" name="LanguageId" data-short-name="@language.NativeName" value="@languageValue" id="Check_@languageValue" @(isCurrentLanguage ? "checked" : "") onchange="filterResults('@languageValue', event);">
317 <label class="form-check-label" for="Check_@languageValue">
318 @language.NativeName
319 </label>
320 </div>
321 }
322 </div>
323 </div>
324 </div>
325 }
326 }
327 <div class="table-responsive">
328 <table class="table table-hover align-middle mb-0" style="table-layout: fixed;" id="assets-table">
329 <thead>
330 <tr>
331 @if (!hideThumbnails)
332 {
333 <th style="width:60px"> </th>
334 }
335 <th>@Translate("Name")</th>
336 <th>@Translate("Asset type")</th>
337 <th>@Translate("Language")</th>
338 <th class="text-end" style="width:100px">@Translate("File type")</th>
339 <th class="text-end d-none d-lg-table-cell">@Translate("Download")</th>
340 </tr>
341 </thead>
342 <tbody class="border-top-0">
343 @foreach (ewiMediaViewModel asset in productAssets)
344 {
345 var assetValue = asset.Value;
346 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Value.Substring(asset.Value.LastIndexOf('/') + 1);
347
348 bool isVideo = false;
349
350 foreach (string format in supportedVideoFormats)
351 { //Videos
352 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0)
353 {
354 isVideo = true;
355 }
356 }
357 // Check if it's a supported format
358 if (!isVideo)
359 {
360 // Get file extension for file type display
361 string filePath = Dynamicweb.Context.Current.Server.MapPath(assetValue);
362 long fileSize = 0;
363 if (File.Exists(filePath))
364 {
365 fileSize = new System.IO.FileInfo(filePath) != null ? new System.IO.FileInfo(filePath).Length / 1024 : 0;
366
367 foreach (string format in allSupportedFormats)
368 {
369 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0)
370 {
371 string show = "hide-row";
372 <tr class="@asset.LanguageId @show">
373 @if (!hideThumbnails)
374 {
375 @RenderAsset(asset)
376 }
377 string languageId = string.Equals(asset.LanguageName, "English", StringComparison.OrdinalIgnoreCase) ? "LANG1" : asset.LanguageId;
378
379 <tr data-language-ids="@languageId" data-language-name="@asset.LanguageName">
380 @if (!hideThumbnails)
381 {
382 <td class="px-0">
383 @{
384 string productName = product.Name;
385 string imagePath = asset.Value;
386 string imageLinkPath = imagePath;
387 imagePath = $"/Admin/Public/GetImage.ashx?image={imagePath}&width=60&format=webp";
388 RatioSettings ratioSettings = GetRatioSettings();
389 }
390 <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" download alt="@productName">
391 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100">
392 <img loading="lazy" src="@imagePath" class="mw-100 mh-100" alt="@productName" />
393 </div>
394 </a>
395 </td>
396 }
397 <td><span class="hide-on-desktop">@Translate("Name")</span> <span>@assetName</span></td>
398 <td><span class="hide-on-desktop">@Translate("Asset type")</span> <span>@asset.AssetSystemName</span></td>
399 <td><span class="hide-on-desktop">@Translate("Language")</span> <span>@asset.LanguageName</span></td>
400 <td class="no-border-bottom"><span class="hide-on-desktop">@Translate("File type")</span> <span>.pdf</span></td>
401 <td class="text-end">
402 <a href="@assetValue" class="download-button" target="_blank">@Translate("Download")</a>
403 </td>
404 </tr>
405 }
406 }
407 </tbody>
408 </table>
409 </div>
410 <script>
411 function filterResults(selectedLang, event) {
412 console.log('Filtering by language:', selectedLang);
413
414 // Prevent event bubbling
415 if (event) {
416 event.stopPropagation();
417 }
418
419 const table = document.getElementById('assets-table');
420 const rows = table.querySelectorAll('tbody tr');
421 const button = document.querySelector('.js-dropdown-btn');
422
423 const checkedBoxes = document.querySelectorAll('input[name="LanguageId"]:checked');
424 const checkedLanguages = Array.from(checkedBoxes).map(cb => cb.value);
425
426 // Handle "All" checkbox behavior - if "All" is checked, uncheck others
427 if (selectedLang === 'ALL') {
428 const allCheckbox = document.querySelector('input[value="ALL"]');
429 if (allCheckbox && allCheckbox.checked) {
430 // Uncheck all other checkboxes
431 document.querySelectorAll('input[name="LanguageId"]:not([value="ALL"])').forEach(cb => {
432 cb.checked = false;
433 });
434 }
435 } else {
436 // If any specific language is checked, uncheck "All"
437 const allCheckbox = document.querySelector('input[value="ALL"]');
438 if (allCheckbox) {
439 allCheckbox.checked = false;
440 }
441 }
442
443 // Re-get checked languages after potential changes
444 const finalCheckedBoxes = document.querySelectorAll('input[name="LanguageId"]:checked');
445 const finalCheckedLanguages = Array.from(finalCheckedBoxes).map(cb => cb.value);
446
447 // Update button text based on selected languages
448 if (finalCheckedLanguages.length === 0) {
449 button.textContent = '@Translate("All")';
450 } else if (finalCheckedLanguages.includes('ALL')) {
451 button.textContent = '@Translate("All")';
452 } else if (finalCheckedLanguages.length === 1) {
453 const selectedCheckbox = document.querySelector(`input[value="${finalCheckedLanguages[0]}"]`);
454 button.textContent = selectedCheckbox ? selectedCheckbox.getAttribute('data-short-name') : 'All';
455 } else {
456 button.textContent = `${finalCheckedLanguages.length} languages selected`;
457 }
458
459 // Filter table rows
460 rows.forEach(row => {
461 const rowLanguageIds = row.getAttribute('data-language-ids');
462 const rowLanguageName = row.getAttribute('data-language-name');
463
464 if (finalCheckedLanguages.length === 0 || finalCheckedLanguages.includes('ALL')) {
465 row.style.display = '';
466 } else {
467 const shouldShow = rowLanguageIds && finalCheckedLanguages.some(lang =>
468 rowLanguageIds === lang ||
469 rowLanguageIds === 'ALL'
470 );
471
472 row.style.display = shouldShow ? '' : 'none';
473 }
474 });
475
476 }
477 document.addEventListener('DOMContentLoaded', function() {
478 // Set initial state - apply filter for pre-checked language
479 const currentLangCheckbox = document.querySelector('input[name="LanguageId"]:checked');
480 if (currentLangCheckbox) {
481 filterResults(currentLangCheckbox.value);
482 } else {
483 // Default to show all if nothing is checked
484 const table = document.getElementById('assets-table');
485 const rows = table.querySelectorAll('tbody tr');
486 rows.forEach(row => {
487 row.style.display = '';
488 });
489 }
490 });
491 </script>
492 @foreach (MediaViewModel asset in assetsList)
493 {
494 var assetName = asset.Value.ToLower();
495 foreach (string videoFormat in supportedVideoFormats)
496 { //Videos
497 if (assetName.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0)
498 {
499 <div class="modal fade js-video-modal" id="modal_@(Model.ID)_@modalVideoNumber" tabindex="-1" aria-labelledby="productDetailsTableModalTitle_@(Model.ID)_@modalVideoNumber" aria-hidden="true">
500 <div class="modal-dialog modal-dialog-centered modal-xl">
501 <div class="modal-content">
502 <div class="modal-header visually-hidden">
503 <h5 class="modal-title" id="productDetailsTableModalTitle_@(Model.ID)_@modalVideoNumber">@product.Title</h5>
504 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
505 </div>
506 <div class="modal-body p-2 p-lg-3 h-100">
507 @{
508 var videoParams = GetVideoParams(asset, "modal");
509 @RenderPartial("Components/VideoPlayer.cshtml", new Dynamicweb.Frontend.FileViewModel { Path = asset.Value }, videoParams)
510 }
511 </div>
512 </div>
513 </div>
514 </div>
515 modalVideoNumber++;
516 }
517 }
518 }
519 </div>
520 }
521 else if (Pageview.IsVisualEditorMode)
522 {
523 <div class="h-100 @theme">
524 <div class="alert alert-dark m-0">
525 @Translate("No assets are available")
526 </div>
527 </div>
528 }
529 }
530