diff --git a/src/UniversalDashboard.Materialize/Components/ud-image-carousel.jsx b/src/UniversalDashboard.Materialize/Components/ud-image-carousel.jsx index cefdf56d..dc191850 100644 --- a/src/UniversalDashboard.Materialize/Components/ud-image-carousel.jsx +++ b/src/UniversalDashboard.Materialize/Components/ud-image-carousel.jsx @@ -1,110 +1,22 @@ import React from 'react'; -import {Carousel} from "react-materialize"; -import $ from "jquery"; - -export default class UdImageCarousel extends React.Component { - - constructor(props){ - super(props); - - this.onCarouselButtonClick = this.onCarouselButtonClick.bind(this); - this.state = { - slideUrlLink:null - } - } - - componentWillMount() { - this.pubSubToken = UniversalDashboard.subscribe(this.props.id, this.onIncomingEvent.bind(this)); - } - - onIncomingEvent(eventName, event) { - if (event.type === "syncElement") { - this.loadData(); +import { Slider, Slide } from "react-materialize"; + +const UDImageCarousel = ({ items, ...props }) => { + + return + { + items.map( + item => + + + } + /> + ) } - } - - onCarouselButtonClick(props){ - let currentButtonParentId = props.id - let activeSlideHref = $(`#${currentButtonParentId} .carousel-item.active`)[0].attributes.href.value - this.setState({ - slideUrlLink:activeSlideHref - }) - } - - render(){ - - // Carousel Items. - var carouselItems = this.props.items.map((item) => { - return
-

{item.title}

- -

{item.text}

-
- }); - - // Main carousel options. - var options = { - fullWidth:this.props.fullWidth, - indicators:this.props.showIndecators, - onCycleTo: () => { - if(this.props.autoCycle){ - this.onCarouselButtonClick(this.props) - setTimeout(() => { - this.instance.instance.next(); - },this.props.speed) - } - else{ - this.onCarouselButtonClick(this.props) - } - } - } - - // Fix item button on main carousel. - var btn = null; - if(this.props.fixButton){ - btn = {this.props.buttonText} - }; - - if(options.fullWidth) { - // Set the width and height of the carousel container - $(`div#${this.props.id}.carousel.carousel-slider`).css({ - "width":`${this.props.width}`, - "height":`${this.props.height}` - }) - } else { - // Set the width and height of the carousel container if it is not a fullWidth - $(`div#${this.props.id}.carousel`).css({ - "width":`${this.props.width}`, - "height":`${this.props.height}` - }) - } - - return ( - - this.instance = x} carouselId={this.props.id} options={options} fixedItem={btn}> - {carouselItems} - - - ) - } +
+} -} \ No newline at end of file +export default UDImageCarousel \ No newline at end of file diff --git a/src/UniversalDashboard.Materialize/Scripts/image-carousel.ps1 b/src/UniversalDashboard.Materialize/Scripts/image-carousel.ps1 index bdd692d8..5a664846 100644 --- a/src/UniversalDashboard.Materialize/Scripts/image-carousel.ps1 +++ b/src/UniversalDashboard.Materialize/Scripts/image-carousel.ps1 @@ -1,89 +1,75 @@ function New-UDImageCarousel { - param( - [Parameter()] + param( + [Parameter()] [ScriptBlock]$Items, - [Parameter()] - [string]$Id = ([Guid]::NewGuid()).ToString(), - [Parameter()] - [switch]$ShowIndicators, - [Parameter()] - [switch]$AutoCycle, - [Parameter()] - [int]$Speed, - [Parameter()] - [string]$Width, - [Parameter()] - [string]$Height, - [Parameter()] - [switch]$FullWidth, - [Parameter()] - [switch]$FixButton, - [Parameter()] - [string]$ButtonText - ) + [Parameter()] + [string]$Id = ([Guid]::NewGuid()).ToString(), + [Parameter()] + [alias("ShowIndicators")] + [switch]$Indicators, + [Parameter()] + [alias("FullWidth")] + [switch]$FullScreen, + [Parameter()] + [alias("Speed")] + [int]$Interval = 6000, + [Parameter()] + [int]$Duration = 500, + [Parameter()] + [int]$Height = 400 + ) - End { - @{ - type = "image-carousel" - isPlugin = $true - assetId = $AssetId + End { - items = $Items.Invoke() - id = $id - showIndicators = $ShowIndicators.IsPresent - autoCycle = $AutoCycle.IsPresent - speed = $Speed - width = $Width - height = $Height - fullWidth = $FullWidth.IsPresent - fixButton = $FixButton.IsPresent - buttonText = $ButtonText - } - } + $Options = @{ + duration = $Duration + height = $Height + interval = $Interval + indicators = $Indicators.IsPresent + } + + @{ + type = "image-carousel" + isPlugin = $true + assetId = $AssetId + items = $Items.Invoke() + id = $id + fullscreen = $FullScreen.IsPresent + options = $Options + } + } } function New-UDImageCarouselItem { - param( - [Parameter()] - [string]$Text, - [Parameter()] - [UniversalDashboard.Models.DashboardColor]$BackgroundColor = "#000", - [Parameter()] - [string]$BackgroundImage, - [Parameter()] - [UniversalDashboard.Models.DashboardColor]$FontColor = "#fff", - [Parameter()] - [string]$BackgroundRepeat, - [Parameter()] - [string]$BackgroundSize, - [Parameter()] - [string]$BackgroundPosition, - [Parameter()] - [string]$TitlePosition, - [Parameter()] - [string]$TextPosition, - [Parameter()] - [string]$Id = ([Guid]::NewGuid()).ToString(), - [Parameter()] - [string]$Title, - [Parameter()] - [string]$Url - ) + param( + [Parameter()] + [hashtable]$Style, + [Parameter()] + [string]$Id = ([Guid]::NewGuid()).ToString(), + [Parameter()] + [alias("BackgroundImage")] + [string]$ImageSource, + [Parameter()] + [string]$Url + ) - End { - @{ - text = $Text - backgroundColor = $BackgroundColor.HtmlColor - backgroundImage = $BackgroundImage - fontColor = $FontColor.HtmlColor - backgroundRepeat = $BackgroundRepeat - backgroundSize = $BackgroundSize - backgroundPosition = $BackgroundPosition - titlePosition = $TitlePosition - textPosition = $TextPosition - id = $id - title = $Title - url = $Url - } - } + End { + @{ + # all those properties can be replace with the Style property + # ---- + # backgroundColor = $BackgroundColor.HtmlColor + # backgroundImage = $BackgroundImage + # fontColor = $FontColor.HtmlColor + # backgroundRepeat = $BackgroundRepeat + # backgroundSize = $BackgroundSize + # backgroundPosition = $BackgroundPosition + # titlePosition = $TitlePosition + # textPosition = $TextPosition + # ---- + style = $Style + id = $id + url = $Url + imageSource = $ImageSource + } + } } \ No newline at end of file diff --git a/src/UniversalDashboard/Help/New-UDImageCarousel.md b/src/UniversalDashboard/Help/New-UDImageCarousel.md index 919622ad..21b95edb 100644 --- a/src/UniversalDashboard/Help/New-UDImageCarousel.md +++ b/src/UniversalDashboard/Help/New-UDImageCarousel.md @@ -26,10 +26,10 @@ Add image carousel to UniversalDashboard you can set the carousel to be full scr ### Example 1 ``` New-UDImageCarousel -Items { - New-UDImageCarouselItem -BackgroundImage https://i0.wp.com/ironmansoftware.com/wp-content/uploads/2019/01/azure.png -BackgroundRepeat = 'no-repeat' -BackgroundSize = 'cover' -BackgroundColor = '#3f51b5' - New-UDImageCarouselItem -BackgroundImage https://i2.wp.com/ironmansoftware.com/wp-content/uploads/2019/01/component.png -BackgroundRepeat = 'no-repeat' -BackgroundSize = 'cover' -BackgroundColor = '#3f51b5' - New-UDImageCarouselItem -BackgroundImage https://i1.wp.com/ironmansoftware.com/wp-content/uploads/2019/01/dsl.png -BackgroundRepeat = 'no-repeat' -BackgroundSize = 'cover' -BackgroundColor = '#3f51b5' -} -Height 650px -FullWidth -FixButton -ButtonText 'GO TO..' -ShowIndicators + New-UDImageCarouselItem -ImageSource https://hdqwalls.com/wallpapers/deadpool-baby-yoda-c6.jpg -Url 'https://hdqwalls.com/wallpapers/deadpool-baby-yoda-c6.jpg' + New-UDImageCarouselItem -ImageSource https://hdqwalls.com/wallpapers/black-widow4k-5b.jpg -Url 'https://hdqwalls.com/wallpapers/black-widow4k-5b.jpg' + New-UDImageCarouselItem -ImageSource https://hdqwalls.com/wallpapers/batman-fire-4k-xv.jpg -Url 'https://hdqwalls.com/wallpapers/batman-fire-4k-xv.jpg' +} -Indicators ``` Create new image carousel with 3 slides and with fixed button on every slide. diff --git a/src/UniversalDashboard/Services/ThemeService.cs b/src/UniversalDashboard/Services/ThemeService.cs index 0d3c8db9..e08c0ca2 100644 --- a/src/UniversalDashboard/Services/ThemeService.cs +++ b/src/UniversalDashboard/Services/ThemeService.cs @@ -12,57 +12,68 @@ namespace UniversalDashboard.Services { - public class ThemeService - { + public class ThemeService + { private static Logger Logger = LogManager.GetLogger(nameof(ThemeService)); private static Dictionary> _cssMap = new Dictionary>(); - public IEnumerable LoadThemes() { + public IEnumerable LoadThemes() + { var assemblyBasePath = Path.GetDirectoryName(this.GetType().GetTypeInfo().Assembly.Location); - var themeDirectory = Path.Combine(assemblyBasePath, "Themes"); + var themeDirectory = Path.Combine(assemblyBasePath, "Themes"); - foreach(var theme in Directory.EnumerateFiles(themeDirectory)) { - using(var powershell = PowerShell.Create()) { + foreach (var theme in Directory.EnumerateFiles(themeDirectory)) + { + using (var powershell = PowerShell.Create()) + { var hashtable = File.ReadAllText(theme); powershell.AddScript(hashtable); var themeHashable = powershell.Invoke().FirstOrDefault()?.BaseObject as Hashtable; - if (powershell.HadErrors) { - foreach(var error in powershell.Streams.Error) { + if (powershell.HadErrors) + { + foreach (var error in powershell.Streams.Error) + { Logger.Warn("Failed to process theme: " + theme); Logger.Warn(error.ErrorDetails.Message); } continue; } - if (themeHashable == null) { + if (themeHashable == null) + { Logger.Warn($"Invalid theme: {theme}"); continue; } - if (!themeHashable.ContainsKey("Name")) { + if (!themeHashable.ContainsKey("Name")) + { Logger.Warn("Invalid theme. Missing Name value."); continue; } - if (!themeHashable.ContainsKey("Definition")) { + if (!themeHashable.ContainsKey("Definition")) + { Logger.Warn("Invalid theme. Missing Definition value."); continue; } var definition = themeHashable["Definition"] as Hashtable; - if (definition == null) { + if (definition == null) + { Logger.Warn("Invalid theme. Definition must be a Hashtable."); continue; } var parent = string.Empty; - if (themeHashable.ContainsKey("Parent")) { + if (themeHashable.ContainsKey("Parent")) + { parent = themeHashable["Parent"].ToString(); } - var atheme = new Theme { + var atheme = new Theme + { Name = themeHashable["Name"].ToString(), Definition = definition, Parent = parent, @@ -74,45 +85,51 @@ public IEnumerable LoadThemes() { } } - public string Create(Theme theme) { + public string Create(Theme theme) + { Logger.Debug("Rendering theme to CSS."); var hashtable = theme.Definition; var parentTheme = LoadThemes().FirstOrDefault(m => m.Name.Equals(theme.Parent, StringComparison.OrdinalIgnoreCase))?.Definition; - if (parentTheme != null) { + if (parentTheme != null) + { Logger.Debug("Merging with parent them: " + theme.Parent); hashtable = MergeHashtables(hashtable, parentTheme); } - if (parentTheme == null && !string.IsNullOrEmpty(theme.Parent)) { + if (parentTheme == null && !string.IsNullOrEmpty(theme.Parent)) + { Logger.Warn("Could not find parent theme: " + theme.Parent); } var stringBuilder = new StringBuilder(); - foreach(object section in hashtable.Keys) { + foreach (object section in hashtable.Keys) + { var identifier = section as string; if (identifier == null) throw new InvalidCastException("Hashtable key is not a string."); var children = hashtable[identifier] as Hashtable; if (children == null) throw new InvalidCastException("Hashtable value is not a hashtable."); - if (_cssMap.ContainsKey(identifier.ToLower())) { + if (_cssMap.ContainsKey(identifier.ToLower())) + { var ids = _cssMap[identifier.ToLower()]; - foreach(var id in ids) { - stringBuilder.AppendLine(id + " {"); + foreach (var id in ids) + { + stringBuilder.AppendLine(id + " {"); TranslateHashtable(children, stringBuilder); stringBuilder.AppendLine("}"); } - } - else + } + else { stringBuilder.AppendLine(identifier + " {"); TranslateHashtable(children, stringBuilder); stringBuilder.AppendLine("}"); } - } + } var themeContent = stringBuilder.ToString(); @@ -121,32 +138,40 @@ public string Create(Theme theme) { return themeContent; } - private Hashtable MergeHashtables(Hashtable child, Hashtable parent) { + private Hashtable MergeHashtables(Hashtable child, Hashtable parent) + { var mergedTable = new Hashtable(); - foreach(var key in parent.Keys) { - if (child.ContainsKey(key)) { + foreach (var key in parent.Keys) + { + if (child.ContainsKey(key)) + { var value = child[key]; var stringValue = value as string; - if (stringValue != null) { + if (stringValue != null) + { mergedTable.Add(key, value); } var hashtableValue = value as Hashtable; var parentHashtableValue = parent[key] as Hashtable; - if (hashtableValue != null && parentHashtableValue != null) { + if (hashtableValue != null && parentHashtableValue != null) + { var mergedTableValue = MergeHashtables(hashtableValue, parentHashtableValue); mergedTable.Add(key, mergedTableValue); } } - else { + else + { mergedTable.Add(key, parent[key]); } } - foreach(var key in child.Keys) { - if (!parent.ContainsKey(key)) { + foreach (var key in child.Keys) + { + if (!parent.ContainsKey(key)) + { mergedTable.Add(key, child[key]); } } @@ -154,25 +179,30 @@ private Hashtable MergeHashtables(Hashtable child, Hashtable parent) { return mergedTable; } - private void TranslateHashtable(Hashtable hashtable, StringBuilder stringBuilder) { - foreach(object section in hashtable.Keys) { + private void TranslateHashtable(Hashtable hashtable, StringBuilder stringBuilder) + { + foreach (object section in hashtable.Keys) + { var identifier = section as string; if (identifier == null) throw new InvalidCastException("Hashtable key is not a string."); var value = hashtable[identifier]; - if (_cssMap.ContainsKey(identifier.ToLower())) { + if (_cssMap.ContainsKey(identifier.ToLower())) + { identifier = _cssMap[identifier.ToLower()].First(); - } + } var setting = value as string; - if (setting != null) { + if (setting != null) + { stringBuilder.AppendLine("\t" + identifier + " : " + setting + ";"); continue; } var children = value as Hashtable; - if (children != null) { + if (children != null) + { stringBuilder.AppendLine(identifier + " {"); TranslateHashtable(children, stringBuilder); stringBuilder.AppendLine("}"); @@ -187,7 +217,8 @@ private static List ToClasses(params string[] values) { return values.ToList(); } - static ThemeService() { + static ThemeService() + { // Classes _cssMap.Add("udcard", ToClasses(".ud-card")); _cssMap.Add("udchart", ToClasses(".ud-chart")); @@ -206,11 +237,15 @@ static ThemeService() { _cssMap.Add("udpagenavigation", ToClasses(".ud-page-navigation")); _cssMap.Add("udrow", ToClasses(".ud-row")); _cssMap.Add("udtable", ToClasses(".ud-table")); + _cssMap.Add("udimagecarouselindicator", ToClasses(".slider .indicators .indicator-item", ".slider .indicators .indicator-item.active")); + _cssMap.Add("udimagecarouselindicatoractive", ToClasses(".slider .indicators .indicator-item.active")); // Properties _cssMap.Add("backgroundcolor", ToClasses("background-color")); _cssMap.Add("fontcolor", ToClasses("color")); + _cssMap.Add("width", ToClasses("width")); + _cssMap.Add("hieght", ToClasses("height")); } - } + } } diff --git a/src/UniversalDashboard/Themes/Default.psd1 b/src/UniversalDashboard/Themes/Default.psd1 index 47fa4d9f..9905537f 100644 --- a/src/UniversalDashboard/Themes/Default.psd1 +++ b/src/UniversalDashboard/Themes/Default.psd1 @@ -76,6 +76,15 @@ $AlternativeBackgroundColor3 = $BackgroundColorBright FontColor = $PrimaryFontColor } + UDImageCarouselIndicator = @{ + Width = '10px' + Hieght = '10px' + } + + UDImageCarouselIndicatorActive = @{ + BackgroundColor = $PrimaryColor + } + #CSS ELEMENTS 'main' = @{ 'padding-left' = "50px" diff --git a/src/client/package-lock.json b/src/client/package-lock.json index 304cb258..4ecaa3b7 100644 --- a/src/client/package-lock.json +++ b/src/client/package-lock.json @@ -1834,7 +1834,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { @@ -2545,7 +2545,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { @@ -2558,7 +2558,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { @@ -2955,7 +2955,7 @@ }, "diffie-hellman": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { @@ -4755,7 +4755,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -4982,7 +4982,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -5861,7 +5861,7 @@ }, "media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, @@ -6266,7 +6266,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -7998,7 +7998,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -8301,7 +8301,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { @@ -8748,7 +8748,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -8803,7 +8803,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": {