Velkommen til vores nye hjemmeside
Vi er glade for at kunne præsentere vores nye og forbedrede hjemmeside!
Error executing template "Designs/Swift/Paragraph/Swift_MenuRelatedContent.cshtml" System.InvalidOperationException: Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct. at System.Collections.Generic.Dictionary`2.FindValue(TKey key) at Dynamicweb.Ecommerce.Shops.Shop.GetTopLevelGroups(String languageId) at Dynamicweb.Ecommerce.Frontend.Navigation.GroupNavigationTreeNodeProvider.GetGroupsBySettings(PageNavigationSettings ecomSettings) at Dynamicweb.Ecommerce.Frontend.Navigation.GroupNavigationTreeNodeProvider.GetNodes(NavigationContext context, NavigationSettings settings, NavigationTreeNode parent) at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.MoveNext() at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.<Any>g__WithEnumerator|36_0[TSource](IEnumerable`1 source) at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source) at CompiledRazorTemplates.Dynamic.RazorEngine_2c44cd34d22043e3b8541efa29bc4c21.ExecuteAsync() at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag) at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template) at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Frontend.Navigation 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 5 @functions { 6 7 NavigationTreeViewModel GetNavigationTreeFromPageId(int pageId = 0, bool includeFolders = false, int startLevel = 1, int stopLevel = 9) 8 { 9 var navigationSettings = new NavigationSettings() 10 { 11 StartLevel = startLevel, 12 StopLevel = stopLevel, 13 RootPageId = pageId, 14 IncludeFoldersAndHidden = includeFolders, 15 ExpandMode = ExpandMode.All, 16 }; 17 18 return Navigation.GetNavigationViewModel(navigationSettings); 19 } 20 21 string GetGroupFieldValue(string fieldSystemName, NavigationTreeNodeViewModel node) 22 { 23 ProductGroupViewModel productGroup = node.GetProductGroup(); 24 string fieldValue = string.Empty; 25 IList<FieldValueViewModel> groupFields = productGroup.GroupFields != null ? productGroup.GroupFields : null; 26 if (groupFields != null) 27 { 28 foreach (FieldValueViewModel field in groupFields) 29 { 30 31 if (field.SystemName == fieldSystemName) 32 { 33 fieldValue = field != null ? field.Value.ToString() : string.Empty; 34 } 35 } 36 } 37 38 return fieldValue; 39 } 40 41 bool NavigationTreeHasChildren(NavigationTreeNodeViewModel rootNode) 42 { 43 foreach (var subNode in rootNode.Nodes) 44 { 45 if (subNode.Nodes.Any()) 46 { 47 return true; 48 } 49 } 50 return false; 51 } 52 53 int GetPageIdFromLink(string pageLink) 54 { 55 return !string.IsNullOrEmpty(pageLink) ? Convert.ToInt32(pageLink.Substring(pageLink.LastIndexOf('=') + 1)) : 0; 56 57 } 58 59 string GetSubmenuType(NavigationTreeNodeViewModel rootNode) 60 { 61 string submenuType = string.Empty; 62 var page = Dynamicweb.Content.Services.Pages.GetPage(rootNode.PageId); 63 var pageType = !string.IsNullOrEmpty(page.ItemType) ? page.ItemType : "Swift_Page"; 64 if (page.PropertyItem is object && page.PropertyItem.TryGetValue("SubmenuType", out object submenuTypeValue)) 65 { 66 submenuType = Dynamicweb.Core.Converter.ToString(submenuTypeValue); 67 } 68 return submenuType; 69 } 70 71 bool IsMegaMenu(NavigationTreeNodeViewModel rootNode, string submenuType) 72 { 73 switch (submenuType) 74 { 75 case "dropdown": 76 return false; 77 case "auto": 78 return NavigationTreeHasChildren(rootNode); 79 default: 80 return true; 81 } 82 } 83 84 string isActive(NavigationTreeNodeViewModel node) 85 { 86 return node.IsActive ? "aria-current='page'" : string.Empty; 87 } 88 89 string isActiveDropdown(NavigationTreeNodeViewModel node) 90 { 91 return node.IsActive ? "class=\"active\"" : string.Empty; 92 } 93 94 bool GetRelatedContentStructure(IEnumerable<NavigationTreeNodeViewModel> relatedContentNodes) 95 { 96 bool relatedContentIsNested = false; 97 98 foreach (var relatedContentNode in relatedContentNodes.Where(node => node.ShowInMenu)) 99 { 100 if (relatedContentNode.Nodes.Any()) 101 { 102 return relatedContentIsNested = true; 103 } 104 } 105 106 return relatedContentIsNested; 107 } 108 109 } 110 111 @{ 112 // Page settings 113 int navigationRootPageId = !string.IsNullOrEmpty(Model.Item.GetString("NavigationRoot")) ? Model.Item.GetLink("NavigationRoot").PageId : 0; 114 var rootNavigation = GetNavigationTreeFromPageId(navigationRootPageId); 115 int maxEndNodes = Model.Item.GetInt32("MaxEndNodes"); 116 string maxEndNodesText = Model.Item.GetString("ShowAllLinkLabel"); 117 118 //CSS Settings 119 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? "theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 120 string spacing = Model.Item.GetRawValueString("Spacing", "compact"); 121 string headerSpacing = spacing == "wide" ? "mb-2" : "mb-1"; 122 string itemSpacing = spacing == "normal" ? "pb-2" : spacing == "wide" ? "pb-3" : "pb-1"; 123 124 string headerAlignment = Model.Item.GetRawValueString("HeaderAlignment", "start"); 125 headerAlignment = $"justify-content-{headerAlignment} text-{headerAlignment}"; 126 127 string textAlignment = Model.Item.GetRawValueString("TextAlignment", "start"); 128 textAlignment = $"text-{textAlignment}"; 129 130 string headerLinkAnimation = Model.Item.GetRawValueString("HeaderLinkAnimation", "left"); 131 headerLinkAnimation = headerLinkAnimation == "none" ? "text-decoration-underline-hover" : $"hover-underline-animation-{headerLinkAnimation}"; 132 133 string menuAlignment = Model.Item.GetRawValueString("MenuAlignment", "start"); 134 menuAlignment = $"justify-content-{menuAlignment}"; 135 136 string clickable = "text-decoration-underline-hover text-decoration-accent-hover"; 137 138 } 139 140 <div class="nav-wrapper megamenu-wrapper item_@Model.Item.SystemName.ToLower()" id="Menu_@Model.ID"> 141 <nav class="d-flex gap-2 @headerAlignment"> 142 @foreach (var rootNode in rootNavigation.Nodes.Where(node => node.ShowInMenu)) 143 { 144 string relatedContentNavigationRoot = GetGroupFieldValue("ProductGroupRelatedContent", rootNode); 145 int relatedContentPageId = !string.IsNullOrEmpty(relatedContentNavigationRoot) ? GetPageIdFromLink(relatedContentNavigationRoot) : 0; 146 var relatedContentNodes = GetNavigationTreeFromPageId(relatedContentPageId, true).Nodes; 147 bool hasRelatedContent = relatedContentNodes.Any() && relatedContentPageId != 0; 148 bool relatedContentIsNested = hasRelatedContent ? GetRelatedContentStructure(relatedContentNodes) : false; 149 bool nodesExist = rootNode.Nodes.Any() || hasRelatedContent; 150 string relatedContentGap = spacing == "wide" ? "gap-4" : "gap-3"; 151 relatedContentGap = relatedContentIsNested ? relatedContentGap : string.Empty; 152 string submenuType = GetSubmenuType(rootNode); 153 bool isMegaMenu = IsMegaMenu(rootNode, submenuType); 154 string submenuTypeCss = isMegaMenu ? "position-static" : string.Empty; 155 string dropdown = nodesExist ? "dropdown" : string.Empty; 156 string dropdownAttributes = nodesExist ? "role=\"button\" data-bs-toggle=\"dropdown\" data-bs-offset=\"0,0\" aria-expanded=\"false\"" : string.Empty; 157 158 <div class="nav-item @dropdown @submenuTypeCss"> 159 @if (rootNode.IsClickable) 160 { 161 162 <a class="nav-link p-2 fw-bold text-uppercase @headerLinkAnimation" href="@rootNode.Link" @dropdownAttributes @isActive(rootNode)> 163 <span class="text-wrap-nowrap">@rootNode.Name</span> 164 </a> 165 } 166 else 167 { 168 <span class="nav-link p-2 fw-bold text-uppercase @headerLinkAnimation" @dropdownAttributes> 169 <span class="text-wrap-nowrap">@rootNode.Name</span> 170 </span> 171 } 172 173 @if (nodesExist) 174 { 175 if (isMegaMenu) 176 { 177 <div class="dropdown-menu border-0 megamenu @theme"> 178 <div class="container-xl overflow-y-auto"> 179 <div class="d-flex py-2 gap-3"> 180 181 @if (hasRelatedContent) 182 { 183 <div class="col-auto megamenu-col d-flex flex-column me-4 pe-4 border-end @relatedContentGap @textAlignment @menuAlignment"> 184 @foreach (var relatedContentNode in relatedContentNodes.Where(node => node.ShowInMenu)) 185 { 186 <div> 187 @if (relatedContentNode.IsClickable) 188 { 189 <a class="nav-link px-0 lh-1 @itemSpacing @headerSpacing @clickable" href="@relatedContentNode.Link" @isActive(relatedContentNode)> 190 <strong>@relatedContentNode.Name</strong> 191 </a> 192 } 193 else 194 { 195 <div class="nav-link px-0 lh-1 pe-none @itemSpacing @headerSpacing" href="@relatedContentNode.Link" @isActive(relatedContentNode)> 196 <strong>@relatedContentNode.Name</strong> 197 </div> 198 } 199 200 @foreach (var relatedContentSubNode in relatedContentNode.Nodes.Where(node => node.ShowInMenu)) 201 { 202 if (relatedContentSubNode.IsClickable) 203 { 204 <a class="nav-link px-0 lh-1 @itemSpacing @clickable" href="@relatedContentSubNode.Link" @isActive(relatedContentSubNode)> 205 <span>@relatedContentSubNode.Name</span> 206 </a> 207 } 208 else 209 { 210 <div class="nav-link px-0 lh-1 pe-none @itemSpacing" href="@relatedContentSubNode.Link"> 211 <span>@relatedContentSubNode.Name</span> 212 </div> 213 } 214 } 215 </div> 216 } 217 </div> 218 219 } 220 221 <div class="col d-flex flex-wrap gap-3 @menuAlignment @textAlignment"> 222 223 @foreach (var subNode in rootNode.Nodes.Where(node => node.ShowInMenu)) 224 { 225 <div class="col-auto megamenu-col @textAlignment"> 226 @if (subNode.IsClickable) 227 { 228 <a class="nav-link px-0 lh-1 @itemSpacing @headerSpacing @clickable" href="@subNode.Link" @isActive(subNode)> 229 <strong>@subNode.Name</strong> 230 </a> 231 } 232 else 233 { 234 <div class="nav-link px-0 lh-1 pe-none @itemSpacing @headerSpacing"> 235 <strong>@subNode.Name</strong> 236 </div> 237 } 238 239 @foreach (var (endNode, index) in subNode.Nodes.Select((node, i) => (node, i))) 240 { 241 if (index < maxEndNodes && endNode.ShowInMenu) 242 { 243 if (endNode.IsClickable) 244 { 245 <a class="nav-link px-0 lh-1 @itemSpacing @clickable" href="@endNode.Link" @isActive(endNode)> 246 @endNode.Name 247 </a> 248 } 249 else 250 { 251 <div class="nav-link px-0 lh-1 pe-none @itemSpacing"> 252 @endNode.Name 253 </div> 254 } 255 256 continue; 257 } 258 259 if (!string.IsNullOrWhiteSpace(maxEndNodesText)) 260 { 261 <a class="nav-link px-0 text-decoration-underline mt-1 lh-1 @itemSpacing" href="@subNode.Link"> 262 @Translate(maxEndNodesText) 263 </a> 264 } 265 266 break; 267 } 268 </div> 269 270 } 271 </div> 272 </div> 273 </div> 274 </div> 275 } 276 else 277 { 278 <ul class="dropdown-menu dropdown-menu-shadow @theme @textAlignment"> 279 280 @if (hasRelatedContent) 281 { 282 foreach (var relatedContentNode in relatedContentNodes) 283 { 284 if (relatedContentNode.IsClickable) 285 { 286 <li @isActiveDropdown(relatedContentNode)> 287 <a class="dropdown-item py-2 lh-1 @clickable" href="@relatedContentNode.Link" @isActive(relatedContentNode)> 288 <strong>@relatedContentNode.Name</strong> 289 </a> 290 </li> 291 } 292 else 293 { 294 <li> 295 <span class="dropdown-item py-2 lh-1 pe-none"> 296 <strong>@relatedContentNode.Name</strong> 297 </span> 298 </li> 299 300 } 301 302 foreach (var relatedContentSubNode in relatedContentNode.Nodes.Where(node => node.ShowInMenu)) 303 { 304 if (relatedContentSubNode.IsClickable) 305 { 306 <li @isActiveDropdown(relatedContentSubNode)> 307 <a class="dropdown-item py-2 lh-1 @clickable" href="@relatedContentSubNode.Link" @isActive(relatedContentSubNode)> 308 <strong>@relatedContentSubNode.Name</strong> 309 </a> 310 </li> 311 } 312 else 313 { 314 <li> 315 <span class="dropdown-item py-2 lh-1 pe-none"> 316 <strong>@relatedContentSubNode.Name</strong> 317 </span> 318 </li> 319 } 320 } 321 } 322 323 <li class="dropdown-divider"></li> 324 } 325 326 @foreach (var subNode in rootNode.Nodes.Where(node => node.ShowInMenu)) 327 { 328 if (subNode.IsClickable) 329 { 330 331 <li @isActiveDropdown(subNode)> 332 <a class="dropdown-item py-2 lh-1 @clickable" href="@subNode.Link" @isActive(subNode)> 333 <strong>@subNode.Name</strong> 334 </a> 335 </li> 336 } 337 else 338 { 339 <li> 340 <span class="dropdown-item py-2 lh-1 pe-none"> 341 <strong>@subNode.Name</strong> 342 </span> 343 </li> 344 } 345 } 346 </ul> 347 } 348 } 349 </div> 350 } 351 </nav> 352 </div> 353 <script type="module"> 354 swift.Menu.setMenuContentOffset('Menu_@Model.ID'); 355 </script> 356
Vi er en dynamisk og visionær aktør inden for den danske sundhedssektor, specialiseret i at levere medicinsk teknisk udstyr, hjælpemidler, inventar og løsninger, der skaber værdi og forbedrer både patientpleje og arbejdsmiljø. Gennem innovation og partnerskaber er vi med til at understøtte fremtidens sundhedssystem, hvor både sundhedspersonale og patienter er i centrum for vores løsninger.
Som agenturførende og eksklusiv forhandler af førende producenter, leverer vi nøje udvalgte produkter og tjenester til sygehuse, klinikker, plejehjem, skoler, institutioner og lign. Vores rolle som partner i sundhedssektoren går ud over det traditionelle leverandørforhold. Vi er forpligtede til at fremme kvalitet, samarbejde og ansvar i alt, hvad vi gør, og vi ser os selv som en drivkraft for positiv forandring.
Vores mission er at levere løsninger, der ikke blot opfylder, men også overgår forventningerne i sundhedssektoren. Vi arbejder tæt sammen med vores kunder for at forstå deres specifikke behov og levere skræddersyede løsninger, der øger effektiviteten, forbedrer arbejdsmiljøet og sikrer den bedst mulige pleje for patienterne.
Vi er drevet af integritet, passion og en stærk dedikation til at gøre en forskel. Vore produkter og løsninger er ikke kun designet til at opfylde nutidens krav – de er skabt med et langsigtet perspektiv, der fremmer sundhed på både et lokalt og globalt plan. Vore værdier reflekterer vores tilgang til arbejde, samarbejde og samfundsansvar, og vi stræber efter at være en betroet partner, der skaber varige relationer baseret på tillid og respekt.
I en verden, hvor sundhed og velvære er centrale elementer i vores daglige liv, er vores mål at fortsætte med at tilbyde innovative, pålidelige og bæredygtige løsninger, der imødekommer de udfordringer, sundhedssektoren står overfor i dag – og i fremtiden. Vi er klar til at hjælpe med at forme en sundere og mere bæredygtig fremtid for både patienter og sundhedspersonale gennem vores visionære løsninger og dedikerede partnerskaber.
Se et udvalg af vores produkter herunder:
Vil I også høre mere om hvordan vi kan hjælpe jer til en lettere hverdag? Så tag fat i os på telefon 86 106 166 eller på info@scan-med.dk
Har du spørgsmål, kommentarer eller brug for hjælp? Udfyld formularen her, eller kontakt os direkte på tlf. 86 106 166. Vi ser frem til at høre fra dig og vender tilbage hurtigst muligt.
Vi vil meget gerne høre fra dig! Har du spørgsmål til vores produkter eller services, brug for vejledning, eller ønsker du at give feedback? Så er du mere end velkommen til at kontakte os.
Du kan udfylde formularen her, så vender vi tilbage til dig hurtigst muligt – som regel inden for 1-2 hverdage.
Foretrækker du direkte kontakt? Du kan også:
Vi sætter pris på din henvendelse og ser frem til at hjælpe dig!