Hi,
please find some ideas for a redesign of webYaST`s "Users" module at: http://home.arcor.de/martin.schmidkunz/
(wasn`t sure if it is a good idea to store all the jquery stuff in my
Export...)
It is based on rlihm`s mock up (http://gagarin.suse.de/).
The basic concept is to show only the most important table entry on a
top level (e.g. user name).
Therefore there are fewer elements on the screen which eases the use
of the module and increases its self-descriptivness and its task
orientation.
On a second level which the user accesses after clicking on the user
name the user can choose whether to "edit" or "delete" the entry.
Again it is avoided to show non-task related information.
Before deleting an item the user is prompted an "Are you sure?" pop up
in order to increase error tolerance and prevent the user from
unintended data loss.
"Edit" shows the settings of the list entry. If more settings are
available they are organized in tabs.
The "Edit" dialog is left either via "Save" or "Cancel"
New list entries can be added via "Add New Item" button on top the list.
Concerning "basic concept"
* "Save"/"Cancel"/"Add" do not work properly in the mock up
* "Add" should be a wizard
* User needs to click "Save" twice (once in the edit tab and then in
the main window) I am not sure whether this is intuitive. What do you
think about that?
* list should be sortable but I am not caple of implementing this
technically
Concerning "Users" module
* When adding a user currently there are 8-9 settings which needed to
be adjusted and some of them seem quite obscure to me. So, what do you
think: which settings should be really editable via GUI?
Currently there are:
Full Name
Groups
Default Group (GID)
Home Directory
Do not create home directory
Login Shell
Login Name
UID Number
Password
Full Name, Login Name, Password and Groups seem quite clear to me but
is it really necessary to set login shell and UID in the GUI? And home
directory? Wouldn`t it make sense to have a sane default which could
be edited via an editor?
* What do you think about showing permissions in the users module as
well? This would seem quite logical to me. What is the reason, why
permissions and users are separated?
Do you have any other topics concerning users module GUI?
Looking forward to your comments!
Best regards and have a happy 2010,
Martin
----------------------------------------------------------------
Martin Schmidkunz
User Experience Specialist
martin.schmidkunz(a)novell.com
+49 (0) 911 740 53-346
-----------------------------------------------------------------
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
-----------------------------------------------------------------
Novell, Inc.
Novell® Making IT Work As One™
Hey Group;
This may be the wrong place to bring this up. However, it is a
perceived Yast2 Printer problem.
I have a Bother MFC-7840W USB laser printer that according to
www.linuxprinter.org it works with Brothers drivers - I have them
installed. lsusb and hwinfo --usb find it. And modprobe has all the
modules required. But Yast2>Hardware>Printer under Add connection
wizard USB will not show any devices or my USB printer. Why would this
be the case.
I went to USB and as I remember I hit enter and on the right side a new
window shows up and is always empty. Yast2 then will not advance until
something is selected
--
73 de Donn Washburn
307 Savoy Street Email:" n5xwb(a)comcast.net "
Sugar Land, TX 77478 LL# 1.281.242.3256
Ham Callsign N5XWB HAMs : " n5xwb(a)arrl.net "
VoIP via Gizmo: bmw_87kbike / via Skype: n5xwbg
BMW MOA #: 4146 - Ambassador
" http://counter.li.org " #279316
--
To unsubscribe, e-mail: yast-devel+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-devel+help(a)opensuse.org
Hi,
in short:
in branch for yast model I add also injector to HttpMock (standard library which is part of ActiveResource to test Rest-service based models) so if you plan write test look at it (or wait until it is merged).
in long:
Main goal to add models to webclient instead of dynamic one is easier testing of functionality which should go to model as controller is only thin layer which serves data. But I found that it is not so easy due to our design and also not so simple situation with rest-service site data.
From my point of view correct testing of rest-service is provide same data as expected from rest-service and test if it work as expected. Now if test is ever present (not much models, I already fill bug) then it is huge mock which in real doesn't test much functionality. So we need some mock service which mock only target rest-service.
Why I choose HttpMock? Even if our local consultant suggest use another framework I choose http because it looks like sufficient for our goal and it is already in ActiveResource so we don't need another gems.
Why not use HttpMock without utilities? Of course it is possible, but you must simulate resource which translate interface to path and also permissions service which is out of test focus and test should not contain permissions service details. Also there is problem with authentication which must be solved on your own. So I create injector which add useful methods to HttpMock.
How to use it in test:
1) define response (we separate at least visually tested data and tests):
TEST_RESPONSE = <<EOF
<test>
<arg1>test</arg1>
</test>
EOF
2) now mock network service ( I suggest use it in setup - but of course for testing exceptions you should redefine it in method)
def setup
ActiveResource::HttpMock.set_authentification #a)
ActiveResource::HttpMock.respond_to do |mock|
header = ActiveResource::HttpMock.authentification_header #b)
mock.resources :'org.opensuse.yast.modules.test' => "/test", :'org.opensuse.yast.modules.test2' => "/test2" #c)
mock.permissions "org.opensuse.yast.modules.test", { :synchronize => true } #d)
mock.get "/test.xml", header, TEST_RESPONSE, 200
mock.post "/test.xml", header, TEST_RESPONSE, 200
mock.get "/test2.xml", header, TEST2_RESPONSE, 200
mock.post "/test2.xml", header, TEST2_RESPONSE, 200
end
end
a) this utility sets authentification and target machine to predefined values
b) authentification_header get hash which is passed to authenticate. It is required in mock header. otherwise it is not matched, but it is hash, so you can add your own values.
c) define resources ( often it is just one, but for example if you use two rest-service (as time use time and ntp) then you define both. after hash argument you pass hash with options, which contains key singleton and policy ( mentioned in previous mail why I found it useless so it is optional, without it I use default which is no policy and single resource)
d) mock permissions controller, just pass prefix and then hash with permission and if it is granted
rest of method is common HttpMock which return expected values, so you can freely test it.
3) test model or controller :)
def test_find_and_save
test = TestModel.find :one
assert_equal "test",test.arg1 #see XML for arg1 value
assert test.save
end
Note: This utility class can be used without yast_model base model, because also dynamic created ActiveResource use this resources (but I do not test it, so expect problems)
If you don't have any complains or suggestion how to improve it I plan to merge it together with yast_model.
welcome any questions, suggestions or complains
Josef
--
Josef Reidinger
YaST team
maintainer of perl-Bootloader, YaST2-Repair, webyast (language,time,basesystem,ntp)
--
To unsubscribe, e-mail: yast-devel+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-devel+help(a)opensuse.org
Hi,
I found an EMail by Martin Schmidkunz about this in my Mailbox.
Which made me look at the concept of YaST at a hole.
YaST today has three (frontend) servers (ncurses, qt, gtk), which should do the garphical visualization of the YaST Modules.
Dose Modules should comuicate through SCR with the system level.
Now WebYaST was added, but not as an (frontend) server to YaST, but as an outside wrapper witch calls the cli of some Modules
(dose with have one), and brings own Modules these Modules.
My question now is why did you through a way the original fronted concept of YaST?
Best regards
Stefan
Gesendet von freenetMail-
Mehr als nur eine E-Mail-Adresse
http://email.freenet.de/dienste/emailoffice/produktuebersicht/basic/mail/in…
WebYaST is now available on http://gitorious.org/opensusehttp://gitorious.org/opensuse/yast-rest-servicehttp://gitorious.org/opensuse/yast-web-clienthttp://gitorious.org/opensuse/ruby-polkit
There is an initial opensuse-yast-developers team defined with access to those
repositories.
To switch your current checkout you only need to edit your .git/config origin
remote
If before it was git@git.opensuse.org:projects/yast/web-client.git
Now it would be:
git@gitorious.org:opensuse/yast-web-client.git
To start, create your account at gitorious.org (you can use openID as well)
and request to be added to opensuse-yast-developers group. (the best would be
to have someone with admin permissions on each location).
You have to configure your ssh public keys in your account settings then:
http://gitorious.org/~yourlogin
The repositories in git.opensuse.org are still accessible, but you can't push
to them anymore. They will stay there until no repositories are left on that
machine.
gitorious provides feeds for each repository pushes, and per each branch
commits with integrated commits reviews and merge requests.
--
Duncan Mac-Vicar P. - Engineering Manager, YaST
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nuernberg)
--
To unsubscribe, e-mail: yast-devel+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-devel+help(a)opensuse.org
Stefan Schubert write:
> ref: refs/heads/master
> commit 4e4d3e055a49b1cf76c2082873b9674b2d8f13eb
> Author: Stefan Schubert <schubi(a)suse.de>
> Date: Tue Dec 22 11:03:14 2009 +0100
>
> cleanup code; bring metrix to the level of status
> ---
> .../status/app/controllers/metrics_controller.rb | 1 -
> plugins/status/app/models/metric.rb | 57 +++++++++++++++++++-
> 2 files changed, 56 insertions(+), 2 deletions(-)
>
> diff --git a/plugins/status/app/controllers/metrics_controller.rb b/plugins/status/app/controllers/metrics_controller.rb
> index c699898..d39205f 100644
> --- a/plugins/status/app/controllers/metrics_controller.rb
> +++ b/plugins/status/app/controllers/metrics_controller.rb
> @@ -1,6 +1,5 @@
> include ApplicationHelper
>
> -require 'scr'
> require 'metric'
> require 'uri'
>
> diff --git a/plugins/status/app/models/metric.rb b/plugins/status/app/models/metric.rb
> index f3e0919..ef8ec02 100644
> --- a/plugins/status/app/models/metric.rb
> +++ b/plugins/status/app/models/metric.rb
> @@ -5,7 +5,26 @@
> # @author Duncan Mac-Vicar P. <dmacvicar(a)suse.de>
> # @author Stefan Schubert <schubi(a)suse.de>
> #
> -require 'yaml'
> +require 'exceptions'
> +
> +class CollectdOutOfSyncError < BackendException
Hi, few notes :)
I know that I also do it, but when you clean code I suggest to move this exception to lib directory of plugin (so plugins/status/lib/collectd_out_of_sync_error.rb to work rails autoload).
> + def initialize(timestamp)
> + @timestamp = timestamp
> + super("Collectd is out of sync.")
> + end
> +
> + def to_xml
> + xml = Builder::XmlMarkup.new({})
> + xml.instruct!
> +
> + xml.error do
> + xml.type "COLLECTD_SYNC_ERROR"
> + xml.description "Collectd is out of sync. Status information can be expected at #{Time.at((a)timestamp.to_i).ctime}."
> +
> + xml.timestamp @timestamp
> + end
> + end
> +end
>
> #
> # This class acts as a model for metrics provided by collectd
> @@ -30,6 +49,7 @@ require 'yaml'
> # end
> #
> class Metric
> + require 'yaml'
>
> COLLECTD_BASE = "/var/lib/collectd"
>
> @@ -41,6 +61,7 @@ class Metric
> # convenience, plugin and instance
> attr_reader :plugin_full
> attr_reader :type_full
> + attr_reader :config
>
> # like identifier, but to be used as a REST id
> # so / are replaced by +
> @@ -123,6 +144,18 @@ class Metric
> # these values can be extracted from the file but we cache
> # them
> @host, @plugin, @plugin_instance, @type, @type_instance = Metric.parse_file_path(path)
> +
> + #find the correct plugin path for the config file
> + plugin_config_dir = "#{RAILS_ROOT}/config" #default
> + Rails.configuration.plugin_paths.each do |plugin_path|
> + if File.directory?(File.join(plugin_path, "status"))
> + plugin_config_dir = plugin_path+"/status/config"
> + Dir.mkdir(plugin_config_dir) unless File.directory?(plugin_config_dir)
^^^
Attention: This doesn't work! yastws doesn't have write permissions to itself so you cannot create directory below RAILS_ROOT! (I already have same problem with writing css cache)
> + break
> + end
> + end
> + #reading configuration file
> + @conf = YAML.load(File.open(File.join(plugin_config_dir, "status_configuration.yaml"))) if File.exists?(File.join(plugin_config_dir, "status_configuration.yaml"))
^^^^
I suggest store to temp variable File.join which you repeat. It is not DRY, effective and you have unnecessary long line:
conf_file = File.join(plugin_config_dir, "status_configuration.yaml")
@conf = YAML.load(File.open(conf_file)) if File.exists? conf_file
> end
>
> # parses the host, plugin, plugin_instance, type and type_instance
> @@ -226,6 +259,13 @@ class Metric
> xml.type type
> xml.type_instance type_instance
>
> + if @conf and @conf.has_key?(id)
You can use try ( but I am not sure if it improve readability so use what you find better)
if @conf.try(:has_key,id)
> + xml.limits() do
> + xml.max(@conf["#{id}"]["max"])
> + xml.min(@conf["#{id}"]["min"])
^^^
I don't understand why you use "#{id}"...if you want string just use id.to_s ... if symbol, then use id.to_sym
> + end
> + end
> +
> # serialize data unless it is disabled
> unless opts.has_key?(:data) and !opts[:data]
> metric_data = data(data_opts)
> @@ -242,6 +282,12 @@ class Metric
> end
>
> end
> +
> + #get last entry of rrd database
> + def self.last_db_entry(file)
> + `/bin/sh -c "LC_ALL=C rrdtool last #{file}"`
^^^
I don't look at whole code, but you must be really sure, that file cannot be compromited otherwise it is security problem. Also be sure, then file doesn't contain special characters. so at least '#{file}' should be used as not much file has ' inside :)
> + end
> +
>
> # runs the rddtool on file with start time and end time
> #
> @@ -250,6 +296,15 @@ class Metric
> #
> # default last 5 minutes from now
> def self.run_rrdtool(file, opts={})
> +
> + #checking if collectd is running
> + ServiceNotRunning.new('collectd') unless collectd_running?
^^^^
I think there is missing raise - test, test,test ;) if you change behavior, test it at first (test-driven development ;)
> +
> + #checking if systemtime is BEHIND the last entry of collectd.
> + #If yes, no data will be available.
> + timestamp = last_db_entry(file)
> + raise CollectdOutOfSyncError.new(timestamp) if Time.now < Time.at(timestamp.to_i)
> +
> stop = opts.has_key?(:stop) ? opts[:stop] : Time.now
> start = opts.has_key?(:start) ? opts[:start] : stop - 300
>
>
--
Josef Reidinger
YaST team
maintainer of perl-Bootloader, YaST2-Repair, webyast (language,time,basesystem,ntp)
--
To unsubscribe, e-mail: yast-devel+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-devel+help(a)opensuse.org
OK: time for christmas whishes :-)
Preji Vam vsem klidne a spokojene vanoce, v novem roce spoutu stesti,
zdravi a dobre pohody!
Ich wünsch euch schöne, erholsame Weihnachten, einen guten Rutsch &
alles Gute für 2010!
I wish you happy and recreative Christmas, a Happy New Year with lots
of health, joy and success!
Best regards,
Martin
----------------------------------------------------------------
Martin Schmidkunz
User Experience Specialist
martin.schmidkunz(a)novell.com
+49 (0) 911 740 53-346
-----------------------------------------------------------------
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
-----------------------------------------------------------------
Novell, Inc.
Novell® Making IT Work As One™
Stefan Schubert write:
> ref: refs/heads/master
> commit 31f399a35839d17d62005b9623562d53af7a6092
> Author: Stefan Schubert <schubi(a)suse.de>
> Date: Tue Dec 22 12:02:12 2009 +0100
>
> code cleanup
> ---
> .../status/app/controllers/metrics_controller.rb | 36 ++++++-------------
> 1 files changed, 12 insertions(+), 24 deletions(-)
>
> diff --git a/plugins/status/app/controllers/metrics_controller.rb b/plugins/status/app/controllers/metrics_controller.rb
> index d39205f..719b6ee 100644
> --- a/plugins/status/app/controllers/metrics_controller.rb
> +++ b/plugins/status/app/controllers/metrics_controller.rb
> @@ -58,20 +58,10 @@ class MetricsController < ApplicationController
> end
> limits = Hash.new
> limits = create_limit(params["status"])
> - f = File.open(File.join(plugin_config_dir, "status_limits.yaml"), "w")
> + f = File.open(File.join(plugin_config_dir, "status_configuration.yaml"), "w")
> f.write(limits.to_yaml)
> f.close
> -
> - @status = Status.new
> - # use now if time is not valid
> - begin
> - stop = params[:stop].blank? ? Time.now : Time.at(params[:stop].to_i)
> - start = params[:start].blank? ? stop - 300 : Time.at(params[:start].to_i)
> - @status.collect_data(start, stop, params[:data])
> - render :show
> - rescue Exception => e
> - render :text => e.to_s, :status => 400 # bad request
> - end
> + render :text => "OK"
^^^
I think that it is not good idea to render text, as you maybe want to check it on frontend and ActiveResource show have problem with it.
> end
>
> # GET /status
> @@ -88,12 +78,13 @@ class MetricsController < ApplicationController
> end
> end
>
> - @metrics = Metric.find(:all, conditions)
> -
> - respond_to do |format|
> - format.xml { render :xml => @metrics.to_xml(:root => 'metrics', :data => false) }
> - end
> + @metric = Metric.find(:all, conditions)
>
> + @data = false
> + @start = nil
> + @stop = nil
> +
> + render :show
^^^^
I think you forget to add show template to render I see only status one.
> end
>
> # GET /status/1
> @@ -102,14 +93,11 @@ class MetricsController < ApplicationController
> #permission_check("org.opensuse.yast.system.status.read")
> begin
> @metric = Metric.find(params[:id])
> - stop = params[:stop].blank? ? Time.now : Time.at(params[:stop].to_i)
> - start = params[:start].blank? ? stop - 300 : Time.at(params[:start].to_i)
> -
> - respond_to do |format|
> - format.xml { render :xml => @metric.to_xml(:start => start, :stop => stop) }
> - end
> + @stop = params[:stop].blank? ? Time.now : Time.at(params[:stop].to_i)
> + @start = params[:start].blank? ? @stop - 300 : Time.at(params[:start].to_i)
^^^^
300 should be defined constant such as DEFAULT_RANGE=300 or similar which say context of number.
> + @data = true
> rescue Exception => e
> - render :text => e.to_s, :status => 400 # bad request
> + render ErrorResult.error(400, 108, e.to_s) and return
^^^
I think it should use same way for reporting exception as rest of webservice, then you don't need to handle client exception (and just server) on frontend. And if I understand code, you want to report bad request, which is typical due to bad parameters and for this purpose you should use InvalidParameters exception which correctly report it to ActiveResource, so you can easily check result of save method on frontend (it behaves as common rails application).
> end
> end
> end
>
--
Josef Reidinger
YaST team
maintainer of perl-Bootloader, YaST2-Repair, webyast (language,time,basesystem,ntp)
--
To unsubscribe, e-mail: yast-devel+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-devel+help(a)opensuse.org
Hi,
I just finish basic functionality of YastModel for webclient. I think that my solution is better then use_activeresource branch :)
It is really intuitive to use.
It is still only in branch waiting for your comments and improvements (branch jr-yastmodel).
How use it? simply :) (example is time module in branch)
create model:
class Stime < ActiveResource::Base # 1) 2)
extend YastModel::Base #3)
model_interface :'org.opensuse.yast.modules.yapi.time' #4)
end
1) Stime because Time already exist and we don't want to overwrite it
2) use ActiveResource not ActiveRecord (gives quite strange errors :)
3) contain definition of model_interface and needed fixtures
4) interface which you use now with load_proxy
And model usage is then same as for common ActiveResource:
@permissions = Stime.permissions #5)
time = Stime.find :one #6)
time.timezone etc...
5) It is class method because it is related to site, user and collection which is also stored in class, so I leave it in same scope
6) :one because time is single resource
And there should be some discuss about format which provide resources.
What is policy? Resource model in rest-service really lack any documentation
Also I am not sure if we require singleton key, as type must know user at webclient and use find :all, :first:, :last etc for multi resource and :one for single resource.
What I found inadequate is href, which should be separated to fixed prefix and changable collection name. Because now we have quite serius problems if we want use namespace for controllers.
Feel free to post any question or suggestion to my solution. If martin agree with it I plan to merge it to master (as it is separate solution).
Thanks
Josef
--
Josef Reidinger
YaST team
maintainer of perl-Bootloader, YaST2-Repair, webyast (language,time,basesystem,ntp)
--
To unsubscribe, e-mail: yast-devel+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-devel+help(a)opensuse.org
Hi,
we now have 'WebYaST' as a standalone project in bugzilla.novell.com,
open to the public.
Being open was the reason for staying under 'openSUSE'. Now I intend to
move all bugs over to 'WebYaST'.
The move will happen either later today or tomorrow.
We have full control over components in Bugzilla, please mail me for
suggestions.
Klaus
---
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
--
To unsubscribe, e-mail: yast-devel+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-devel+help(a)opensuse.org