Node-Red configuration
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ui_theme.html 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <script type="text/javascript">
  2. RED.nodes.registerType('ui-theme', {
  3. category: 'config',
  4. defaults: {
  5. name: {
  6. value: RED._('@flowfuse/node-red-dashboard/ui-theme:ui-theme.label.themeName'),
  7. required: true
  8. },
  9. // colors
  10. colors: {
  11. value: {
  12. surface: '#ffffff',
  13. primary: '#0094CE',
  14. bgPage: '#eeeeee',
  15. groupBg: '#ffffff',
  16. groupOutline: '#cccccc'
  17. }
  18. },
  19. // sizes
  20. sizes: {
  21. value: {
  22. density: 'default',
  23. pagePadding: '12px',
  24. groupGap: '12px',
  25. groupBorderRadius: '4px',
  26. widgetGap: '12px'
  27. }
  28. }
  29. },
  30. oneditprepare: function () {
  31. function hasProperty (obj, prop) {
  32. return !!Object.prototype.hasOwnProperty.call(obj, prop)
  33. }
  34. if (!this.colors) {
  35. this.colors = {}
  36. // set default values
  37. this.colors.surface = '#ffffff'
  38. this.colors.primary = '#0094CE'
  39. // pages
  40. this.colors.bgPage = '#eeeeee'
  41. // groups
  42. this.colors.groupBg = '#ffffff'
  43. this.colors.groupOutline = '#cccccc'
  44. }
  45. if (!this.sizes) {
  46. this.sizes = {}
  47. }
  48. // set default values
  49. if (!hasProperty(this.sizes, 'density')) {
  50. this.sizes.density = 'default'
  51. }
  52. if (!hasProperty(this.sizes, 'pagePadding')) {
  53. this.sizes.pagePadding = '12px'
  54. }
  55. if (!hasProperty(this.sizes, 'groupGap')) {
  56. this.sizes.groupGap = '12px'
  57. }
  58. if (!hasProperty(this.sizes, 'groupBorderRadius')) {
  59. this.sizes.groupBorderRadius = '4px'
  60. }
  61. if (!hasProperty(this.sizes, 'widgetGap')) {
  62. this.sizes.widgetGap = '12px'
  63. }
  64. // loop over keys in this.colors
  65. Object.keys(this.colors).forEach((color) => {
  66. // get the value of the key
  67. const value = this.colors[color]
  68. // set the value of the input
  69. $('#node-config-input-' + color).val(value)
  70. })
  71. // loop over keys in this.sizes
  72. Object.keys(this.sizes).forEach((size) => {
  73. // get the value of the key
  74. let value = this.sizes[size]
  75. // value is a number, add `px` to the end
  76. value += (parseFloat(value).toString() === value) ? 'px' : ''
  77. // set the value of the input
  78. $('#node-config-input-' + size).val(value)
  79. })
  80. // update label b/g to match the colour input values
  81. // this provides nicer styling than the default browser styling
  82. const colorWrappers = $('.color-picker-wrapper')
  83. colorWrappers.each(function (i) {
  84. const wrapper = $(this)
  85. const colorPicker = wrapper.children("input[type='color']").eq(0)
  86. colorPicker.on('change', () => {
  87. wrapper.css('background-color', colorPicker.val())
  88. })
  89. wrapper.css('background-color', colorPicker.val())
  90. })
  91. },
  92. oneditsave: function () {
  93. // update our config values from the input values
  94. Object.keys(this.colors).forEach((color) => {
  95. // set the value of the input
  96. this.colors[color] = $('#node-config-input-' + color).val()
  97. })
  98. // update our config values from the input values
  99. Object.keys(this.sizes).forEach((size) => {
  100. // get the value of the key
  101. let value = $('#node-config-input-' + size).val()
  102. // value is a number, add `px` to the end
  103. value += (parseFloat(value).toString() === value) ? 'px' : ''
  104. // set the value of the input
  105. this.sizes[size] = value
  106. })
  107. },
  108. label: function () {
  109. return `${this.name}` || 'UI Theme'
  110. }
  111. })
  112. </script>
  113. <script type="text/html" data-template-name="ui-theme">
  114. <div class="form-row">
  115. <label for="node-config-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></label>
  116. <input type="text" id="node-config-input-name" data-i18n="[placeholder]node-red:common.label.name">
  117. </div>
  118. <h3 style="margin: 0; margin-bottom: 6px; border-bottom: 1px solid #eee; padding-bottom: 3px;" data-i18n="ui-theme.label.colors"></h3>
  119. <div class="form-row" style="margin-bottom: 3px;">
  120. <h4 style="margin-bottom: 0;"><i class="fa fa-bar-chart"></i> <span data-i18n="ui-theme.label.dashboard"></h4>
  121. </div>
  122. <div class="form-row form-row-flex labels-right" style="margin-bottom: 3px; gap: 9px;">
  123. <div>
  124. <label data-i18n="ui-theme.label.header"></label>
  125. <label class="color-picker-wrapper" for="node-config-input-primary" style="width: 100px; height: 32px; border-radius: 6px; border: 1px solid #ccc">
  126. <input type="color" id="node-config-input-surface" style="opacity: 0; width: 100%;"/>
  127. </label>
  128. </div>
  129. <div>
  130. <label data-i18n="ui-theme.label.primary"></label>
  131. <label class="color-picker-wrapper" for="node-config-input-primary" style="width: 100px; height: 32px; border-radius: 6px; border: 1px solid #ccc">
  132. <input type="color" id="node-config-input-primary" style="opacity: 0; width: 100%;"/>
  133. </label>
  134. </div>
  135. </div>
  136. <div class="form-row" style="margin-bottom: 3px;">
  137. <h4 style="margin-bottom: 0;"><i class="fa fa-object-group"></i> <span data-i18n="ui-theme.label.pages"></h4>
  138. </div>
  139. <div class="form-row labels-right" style="margin-bottom: 3px;">
  140. <label data-i18n="ui-theme.label.background"></label>
  141. <label class="color-picker-wrapper" for="node-config-input-background" style="width: 100px; height: 32px; border-radius: 6px; border: 1px solid #ccc">
  142. <input type="color" id="node-config-input-bgPage" style="opacity: 0; width: 100%;"/>
  143. </label>
  144. </div>
  145. <div class="form-row" style="margin-bottom: 3px;">
  146. <h4 style="margin-bottom: 0;"><i class="fa fa-table"></i> <span data-i18n="ui-theme.label.groups"></h4>
  147. </div>
  148. <div class="form-row form-row-flex labels-right" style="margin-bottom: 3px; gap: 9px;">
  149. <div>
  150. <label data-i18n="ui-theme.label.background"></label>
  151. <label class="color-picker-wrapper" for="node-config-input-background" style="width: 100px; height: 32px; border-radius: 6px; border: 1px solid #ccc">
  152. <input type="color" id="node-config-input-groupBg" style="opacity: 0; width: 100%;"/>
  153. </label>
  154. </div>
  155. <div>
  156. <label data-i18n="ui-theme.label.outline"></label>
  157. <label class="color-picker-wrapper" for="node-config-input-background" style="width: 100px; height: 32px; border-radius: 6px; border: 1px solid #ccc">
  158. <input type="color" id="node-config-input-groupOutline" style="opacity: 0; width: 100%;"/>
  159. </label>
  160. </div>
  161. </div>
  162. <h3 style="margin: 12px 0 6px; border-bottom: 1px solid #eee; padding-bottom: 3px;" data-i18n="ui-theme.label.sizings"></h3>
  163. <div class="form-row">
  164. <label for="node-config-input-density" data-i18n="ui-theme.label.density"></label>
  165. <select type="text" id="node-config-input-density">
  166. <option value="default" data-i18n="ui-theme.label.default"></option>
  167. <option value="comfortable" data-i18n="ui-theme.label.comfortable"></option>
  168. <option value="compact" data-i18n="ui-theme.label.compact"></option>
  169. </select>
  170. </div>
  171. <div class="form-row">
  172. <label for="node-config-input-pagePadding" data-i18n="ui-theme.label.pagePadding"></label>
  173. <input type="text" id="node-config-input-pagePadding">
  174. </div>
  175. <div class="form-row">
  176. <label for="node-config-input-groupGap" data-i18n="ui-theme.label.groupGap"></label>
  177. <input type="text" id="node-config-input-groupGap">
  178. </div>
  179. <div class="form-row">
  180. <label for="node-config-input-groupBorderRadius" data-i18n="ui-theme.label.groupBorderRadius"></label>
  181. <input type="text" id="node-config-input-groupBorderRadius">
  182. </div>
  183. <div class="form-row">
  184. <label for="node-config-input-widgetGap" data-i18n="ui-theme.label.widgetGap"></label>
  185. <input type="text" id="node-config-input-widgetGap">
  186. </div>
  187. </script>
  188. <style>
  189. .labels-right label {
  190. text-align: right;
  191. }
  192. .labels-right label:first-child {
  193. padding-right: 3px;
  194. }
  195. .labels-right label:first-child:after {
  196. content: ':';
  197. }
  198. </style>