Skip to content

Commit

Permalink
Merge aa95d94 into 87280a5
Browse files Browse the repository at this point in the history
  • Loading branch information
mvidner committed Jan 24, 2019
2 parents 87280a5 + aa95d94 commit 2e1c847
Show file tree
Hide file tree
Showing 20 changed files with 445 additions and 21 deletions.
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

# 2 space indentation
[*.rb]
indent_style = space
indent_size = 2
4 changes: 4 additions & 0 deletions src/lib/y2configuration_management/salt/form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

require "yaml"
require "yast"
require "y2configuration_management/salt/form_condition"
require "y2configuration_management/salt/form_element_locator"
require "y2configuration_management/salt/form_element_factory"
require "y2configuration_management/salt/form_element_helpers"
Expand Down Expand Up @@ -96,6 +97,8 @@ class FormElement
attr_reader :scope
# @return [Boolean]
attr_reader :optional
# @return [FormCondition,nil]
attr_reader :visible_if

# Constructor
#
Expand All @@ -109,6 +112,7 @@ def initialize(id, spec, parent:)
@scope = spec.fetch("$scope", "system").to_sym
@optional = spec["$optional"] if spec["$optional"]
@parent = parent
@visible_if = FormCondition.parse(spec.fetch("$visibleIf", ""), context: locator)
end

# Return the absolute locator of this form element in the actual form
Expand Down
3 changes: 1 addition & 2 deletions src/lib/y2configuration_management/salt/form_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def build(form_element)
elements = scalar ? [form_element] : form_element.elements
widgets = Array(elements).map { |e| build_element(e) }
Y2ConfigurationManagement::Widgets::Form.new(
widgets, scalar: scalar
widgets, controller, scalar: scalar
)
end

Expand Down Expand Up @@ -96,7 +96,6 @@ def build_group(group)
children = group.elements.map do |element_spec|
build_element(element_spec)
end
_visible = group.type == :group # FIXME: use this
Y2ConfigurationManagement::Widgets::Group.new(group, children)
end

Expand Down
100 changes: 100 additions & 0 deletions src/lib/y2configuration_management/salt/form_condition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Copyright (c) [2019] SUSE LLC
#
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, contact SUSE LLC.
#
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

module Y2ConfigurationManagement
module Salt
# A boolean condition operating on a value in the form,
# used for widget visibility ($visibleIf).
class FormCondition
class ParseError < RuntimeError
end

# @param s [String]
# @param context [FormElementLocator] for resolving relative expressions
# @return [FormCondition,nil]
def self.parse(s, context:)
if s.empty?
nil
# This matches checkVisibilityCondition in FormulaComponentGenerator.js
# TODO: specify it better
elsif s.include?("==")
parts = s.split("==").map(&:strip)
locator = parse_locator(parts[0].strip, context)
value = parse_value(parts[1].strip)
EqualCondition.new(locator: locator, value: value)
elsif s.include?("!=")
parts = s.split("!=").map(&:strip)
locator = parse_locator(parts[0], context)
value = parse_value(parts[1])
NotEqualCondition.new(locator: locator, value: value)
else
raise ParseError, "Expecting equality or inequality: #{s.inspect}"
end
end

# @param s [String]
# @param context [FormElementLocator] for resolving relative expressions
# @return [FormElementLocator]
def self.parse_locator(s, context)
if s.start_with? "."
while s.start_with? "."
s = s[1..-1]
context = context.parent
end
else
context = FormElementLocator.new([:root])
end
s_parts = s.split("#").map(&:to_sym)
context.join(* s_parts)
end

# @param s [String]
# @return [String] (conditions compare stringified values)
def self.parse_value(s)
if (s[0] == "'" && s[-1] == "'") || (s[0] == "\"" && s[-1] == "\"")
s[1..-2]
else
s
end
end
end

# A {FormCondition} checking if a widget is equal to a constant
class EqualCondition < FormCondition
def initialize(locator:, value:)
@locator = locator
@value = value
end

# @param data [FormData]
def evaluate(data)
left = data.get(@locator).to_s
right = @value.to_s
left == right
end
end

# A {FormCondition} checking if a widget is not equal to a constant
class NotEqualCondition < EqualCondition
def evaluate(data)
!super
end
end
end
end
9 changes: 9 additions & 0 deletions src/lib/y2configuration_management/salt/form_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ def remove(relative_locator)
refresh_top_form
end

def update_visibility
state.form_widget.store
form_result = state.form_widget.result
local_data = FormData.new(form)
local_data.update(state.locator, form_result)
state.form_widget.update_visibility(local_data)
end

private

# @return [Form]
Expand All @@ -133,6 +141,7 @@ def form_builder
# Refreshes the most recently open form widget
def refresh_top_form
state.form_widget.refresh(get(state.locator))
state.form_widget.update_visibility(data)
end

# Displays a popup
Expand Down
4 changes: 3 additions & 1 deletion src/lib/y2configuration_management/salt/form_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ def initialize(form, initial = {})
#
# @param locator [FormElementLocator] Locator of the element
def get(locator)
find_by_locator(@data, locator) || default_for(locator)
value = find_by_locator(@data, locator)
value = default_for(locator) if value.nil?
value
end

# Updates an element's value
Expand Down
3 changes: 3 additions & 0 deletions src/lib/y2configuration_management/widgets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

require "y2configuration_management/widgets/visibility_switcher"
require "y2configuration_management/widgets/salt_visibility_switcher"

require "y2configuration_management/widgets/base_mixin"
require "y2configuration_management/widgets/boolean"
require "y2configuration_management/widgets/color"
Expand Down
27 changes: 24 additions & 3 deletions src/lib/y2configuration_management/widgets/boolean.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,45 @@ module Y2ConfigurationManagement
# This module contains the widgets which are used to display forms for Salt formulas
module Widgets
# This class represents a boolean (checkbox) field. TODO: is tristate possible?
class Boolean < ::CWM::CheckBox
class Boolean < VisibilitySwitcher
include BaseMixin

# @return [Boolean] Default value
attr_reader :default

include SaltVisibilitySwitcher

# A helper to go inside a ReplacePoint
class CheckBox < ::CWM::CheckBox
# @return [String] Widget label
attr_reader :label

def initialize(id:, label:)
self.widget_id = id
@label = label
end

# TODO: only if I am mentioned in a visible_if
def opt
[:notify]
end
end

# Constructor
#
# @param spec [Y2ConfigurationManagement::Salt::FormElement] Element specification
def initialize(spec)
initialize_base(spec)
@default = spec.default == true # nil -> false
self.widget_id = "boolean:#{spec.id}"

inner = CheckBox.new(id: "boolean:#{spec.id}", label: spec.label)
super(id: "vis:#{spec.id}", widget: inner)
initialize_salt_visibility_switcher(spec.visible_if)
end

# @see CWM::AbstractWidget
def init
self.value = default
super(default)
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions src/lib/y2configuration_management/widgets/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class Collection < ::CWM::CustomWidget
# @return [Array<Object>] List of objects which are included in the collection
attr_accessor :value

include SaltVisibilitySwitcher

# @return [Array<CWM::AbstractWidget>] Parent widget
attr_accessor :parent

Expand Down
16 changes: 15 additions & 1 deletion src/lib/y2configuration_management/widgets/form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,13 @@ class Form < ::CWM::CustomWidget
#
# @param children [Array<CWM::AbstractWidget>] Widgets included in the form
# @param scalar [Boolean] Determines whether the form stores are scalar value
def initialize(children, scalar: false)
def initialize(children, controller, scalar: false)
@value = scalar ? nil : {}
@scalar = scalar
add_children(*children)
@controller = controller
self.handle_all_events = true
super()
end

# This method propagates the values to the underlying widgets.
Expand Down Expand Up @@ -113,6 +116,17 @@ def refresh(values)
set_children_contents
end

def handle
@controller.update_visibility
nil
end

def update_visibility(data)
children.each do |widget|
widget.update_visibility(data)
end
end

# Add children widgets
#
# @param widgets [Array<CWM::AbstractWidget>] Widgets to add to the form
Expand Down
14 changes: 13 additions & 1 deletion src/lib/y2configuration_management/widgets/group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Group < ::CWM::CustomWidget
def initialize(spec, children)
textdomain "configuration_management"
initialize_base(spec)
@has_frame = spec.type == :group
self.widget_id = "group:#{spec.id}"
add_children(*children)
end
Expand All @@ -43,7 +44,12 @@ def initialize(spec, children)
#
# @return [Yast::Term]
def contents
VBox(*children)
c = VBox(*children)
if @has_frame
Frame(label, c)
else
c
end
end

# Sets the value for the form
Expand Down Expand Up @@ -73,6 +79,12 @@ def value
children.reduce({}) { |a, e| a.merge(e.id => e.value) }
end

def update_visibility(data)
children.each do |widget|
widget.update_visibility(data) if widget.respond_to? :update_visibility
end
end

# Add children widgets
#
# @param widgets [Array<CWM::AbstractWidget>] Widgets to add to the group
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright (c) [2019] SUSE LLC
#
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, contact SUSE LLC.
#
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

require "cwm"

module Y2ConfigurationManagement
module Widgets
# Salt-forms specific visibility switching
module SaltVisibilitySwitcher
# @return [FormCondition,nil]
attr_reader :visible_if

def initialize_salt_visibility_switcher(visible_if)
@visible_if = visible_if
end

# Automatic invisibility: when the form controller asks us,
# we evaluate a condition and update our visibility
# @param data [FormData]
def update_visibility(data)
return unless @visible_if
self.visible = @visible_if.evaluate(data)
end
end
end
end
2 changes: 2 additions & 0 deletions src/lib/y2configuration_management/widgets/select.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class Select < ::CWM::ComboBox
# @return [String,nil] Default value
attr_reader :default

include SaltVisibilitySwitcher

# Constructor
#
# @param spec [Y2ConfigurationManagement::Salt::FormElement] Element specification
Expand Down

0 comments on commit 2e1c847

Please sign in to comment.