using config.groovy in gwt for user preference - grails

I have a gwt and grails legacy app that I'm upgrading and modifying.. Its a reservation calendar basically with different "views".. the problem I'm having is I want the user to be able to choose a default view for themselves upon logging in..I've done this with a grails only application before but gwt is much different..how can I pass something from config.groovy to the gwt part that select which view to show..and this view isn't a view like a grails view..think of it like restaurants..and a user may only want to see the reservations for a particular restaurant instead of the default of all restaurants

Maybe not a direct answer to your question but you can just make a ordinary GWT remote service UserPreferencesService which will store user preferences
public interface UserPreferencesService extends RemoteService {
List<Restaurant> getRestaurants(Account user);
void setRestaurants(Account user, List<Restaurant> restaurants);
}
In your entry point you can then make a decision on what kind of view you'll show to user
public final class Application implements EntryPoint {
private AuthServiceAsync authService =
GWT.create(AuthService.class);
private UserPreferencesAsync preferencesService =
GWT.create(UserPreferencesService.class);
#Override
public void onModuleLoad() {
// handle login
authService.getAccount(new Callback<Account>() {
#Override
public void onSuccess(final Account account) {
// check if user have a preferred restourants
preferencesService.getRestaurants(account,
new Callback<Account>() {
#Override
public void onSuccess(final List<Restaurant> restaurants) {
// user did not select any restaurants yet.
// Show a selection widget
if (restaurants.isEmpty) {
RestaurantSelectorWidget widget =
new RestaurantSelectorWidget();
// your custom handler here
widget.addHandler(new Handler() {
#Override
public void onSelected(/*...*/) {
// save user preferences
// and switch to normal view
}
})
RootPanel.get("container")
.add(widget);
} else {
// show normal view
}
}
}
}
}
}
}
}
Also you may take look to this plugin which is adds GWT support to grails.

Related

Conditional context menu with Vaadin grid

In my Vaadin application I have a grid displaying book information. I do need to add a context menu to the grid but it shall be conditional.
For anonymous user (i.e. hasn't logged in yet) there shall be no context menu. For logged in user, menu items shall depend on user privileges. I.e. regular user can only add or edit/delete his personal book review. Admin users shall be able to do more - edit book information, change status, etc.
Shall I set/reset context menu after login occurs? If two users simultaneously using the application, will they get different context menus? When user logged out, shall I set context menu to null?
No code is written yet, therefore I am not providing it here.
You advise will be greatly appreciated.
I found the solution by extending GridContextMenu and adding User property into it;
public class BookContextMenu extends GridContextMenu<Book> {
private User user;
private final PanelsConfig config;
private final GridMenuItem<Book> editBookMenuItem;
private final GridMenuItem<Book> reviewMenuItem;
public BookContextMenu(PanelsConfig panelsConfig) {
super();
this.config = panelsConfig;
this.editBookMenuItem = addItem("Edit book",
event -> event.getItem().ifPresent(book -> {
BookPanel bookPanel = config.getBookPanel();
bookPanel.setBook(book);
bookPanel.open();
}));
this.reviewMenuItem = addItem("Reader's review",
event -> event.getItem().ifPresent(book -> {
ReviewPanel reviewPanel = config.getReviewPanel();
reviewPanel.setUser(user);
reviewPanel.setBook(book);
reviewPanel.open();
}));
if (user == null || !user.isReaderActive()) {
editBookMenuItem.setVisible(false);
reviewMenuItem.setVisible(false);
} else if (!user.isAdmin()) {
editBookMenuItem.setVisible(false);
}
}
public void setUser(User user) {
this.user = user;
if (user == null || !user.isActive()) {
editBookMenuItem.setVisible(false);
reviewMenuItem.setVisible(false);
} else {
this.setEnabled(true);
reviewMenuItem.setVisible(true);
if (user.isAdmin()) {
editBookMenuItem.setVisible(true);
}
}
}
}

how to inflate different layouts in Firebase Recycler Adapter

I have a chat activity and trying to inflate different layouts for the sender and receiver. so far I can retrieve data for the firebase realtime database but sender and receiver have the same layout, I have created layout second layout and tried with viewType but can't figure out how to assign the current user to a cretin layout, please help :(
chat activity
if (!employee)
{
FirebaseRecyclerOptions options = new FirebaseRecyclerOptions.Builder<ChatMessageModel>()
.setQuery(FirebaseDatabase.getInstance().getReference().child("client_emp_messages")
.child(formattedDate+uid), ChatMessageModel.class)
.build();
}
else
{
// employee
Bundle bundle = getIntent().getExtras();
String d = bundle.getString("path_to_client_realtime_db");
options = new FirebaseRecyclerOptions.Builder<ChatMessageModel>()
.setQuery(FirebaseDatabase.getInstance().getReference().child("client_emp_messages")
.child(d), ChatMessageModel.class)
.build();
}
adapter = new ChatAdapter(options);
nMessageList.setAdapter(adapter);
chat adapter
public class ChatAdapter extends FirebaseRecyclerAdapter<ChatMessageModel, ChatAdapter.ChatViewHolder>
{
public ChatAdapter(#NonNull FirebaseRecyclerOptions<ChatMessageModel> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull ChatViewHolder holder, int i, #NonNull ChatMessageModel model) {
holder.nMessage_text_view.setText(model.getMessage());
}
#NonNull
#Override
public ChatViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_single_layout, parent, false);
return new ChatViewHolder(view);
}
class ChatViewHolder extends RecyclerView.ViewHolder
{
TextView nMessage_text_view;
public ChatViewHolder(#NonNull View itemView) {
super(itemView);
nMessage_text_view = itemView.findViewById(R.id.message_text_view);
}
}
}
What I suggest you is to make one layout. like the sender on the right side and receiver on the left side. you can use it with the help of a linear layout or relative layout. and set their visibility Invisible.
So download the message data from the database and check it by user id token. If it data matches with the current user token then display it in the right column and set visibility Visible and vice versa.
For that, you just need to store the user token with the message in the database.
Hope you understand it. Thanks

Users activity feed in orchard cms

we are working on orchard, we need to create a activity feed of users,means all the activities of users like updations,deletions, or insertions of their details neddto be shownas they did in their home page. how to create custom activity feed using orchard cms? or is there any existing design for that ?
You can intercept "activities" on user details by creating a content handler for the UserPart like so
public class MyHandler : Orchard.ContentManagement.Handlers.ContentHandler
{
// public
public MyHandler()
{
// listen to user events
OnPublishing<Orchard.Users.Models.UserPart>(UserPublishing);
OnRemoving<Orchard.Users.Models.UserPart>(UserRemoving);
...
}
// private
private void UserPublishing(Orchard.ContentManagement.Handlers.PublishContentContext aContext, Orchard.Users.Models.UserPart aUserPart)
{
// do some stuff on user publishing
}
private void UserRemoving(Orchard.ContentManagement.Handlers.RemoveContentContext aContext, Orchard.Users.Models.UserPart aUserPart)
{
// do some stuff on user removal
}
...
}
Extensive documentation can be found here:
http://docs.orchardproject.net/en/latest/Documentation/Understanding-content-handlers/
There is also a module called Orchard Audit which seems to record user activities:
http://gallery.orchardproject.net/Packages/Orchard.Module.Downplay.Audit

How to extend Jenkins job page with new links and icons

I'm developing my first Jenkins plugin and followed the tutorial at wiki.jenkins-ci.org. After adding a BuildStep and generating the results I now want to publish them to the user. I would like to do this via a new link entry on the job page and a corrsponding result view page.
Unfortunatelly I do not find the right extension points for the navigation bar at the left side, the main navigation links in the center as well as the new target page. Can somebody point me in the right direction or give me a link to a tutorial or blog post that explains this scenario?
Thanks
Root Action and Actions are different. The first one goes only to initial page (root), the second one can be attach to a Project/Job or to a Build.
To create a Root Action, just need to create a class that it's:
Annotated with #Extension (so it can be found and automatically
loaded by Jenkins)
Implements RootAction Interface
Override 3 methods: getIconFileName(), getDisplayName() and getUrlName()
For example:
#Extension
public class GoogleRootAction implements RootAction{
#Override
public String getIconFileName() {
return "clipboard.png";
}
#Override
public String getDisplayName() {
return "Google URL";
}
#Override
public String getUrlName() {
return "http://www.google.pt";
}
}
To create an Action at a Project it's more complicated, and there's more than a way, depending of what you want.
But first, the class Action itself is the easy part, since it's very similar to a class RootAction. It's not annotated with #Extension and implements Action interface instead of RootAction.
For example:
public class LatestConsoleProjectAction implements Action {
private AbstractProject<?, ?> project;
#Override
public String getIconFileName() {
return (Jenkins.RESOURCE_PATH + "/images/48x48/terminal.png").replaceFirst("^/", "");
}
#Override
public String getDisplayName() {
return Messages.Latest_Console_Project_Action();
}
#Override
public String getUrlName() {
return "lastBuild/console";
}
public LatestConsoleProjectAction(final AbstractProject<?, ?> project) {
this.project = project;
}
}
The tricky part is to inform jenkins that this class Action exists. As I said, there are different ways.
For instance, one can associate an Action to a Builder or Publisher or other by just overriding getProjectAction() method at those classes.
For example:
#Override
public Action getProjectAction(AbstractProject<?, ?> project) {
return new LatestConsoleProjectAction(project);
}
But this way, the Action link will only show on Project left menu, if the corresponding Builder or Publisher is used by the job (or selected at Job configurations).
Another way, that always shows your Action link on left menu, it's create a factory class to inform jenkins. There are many factories, but at my example I will use TransientProjectActionFactory class.
For this, one will need to create a class that:
It's annotated with #Extensions
Extends TransientProjectActionFactory class (or another Factory class)
Override createFor method to create your class Action associated with Project object
For example:
#Extension
public class LatestConsoleProjectActionFactory extends TransientProjectActionFactory {
#Override
public Collection<? extends Action> createFor(AbstractProject abstractProject) {
return Collections.singletonList(new LatestConsoleProjectAction(abstractProject));
}
}
One can still filter project object to just the projects types you want. The one you don't want, just return Collections.emptyList().
Beside this two ways, I think there are others. You can see this link to reference:
https://wiki.jenkins-ci.org/display/JENKINS/Action+and+its+family+of+subtypes
Although, they refer to addAction method and others, but I couldn't use it (I have 2.19.2 Jenkins version).
Also they refer groovy, but I didn't try it, since I want to stick with Java :)
Btw, my example will create an action link to open console page of last build. Useful to avoid selecting last build and then select his console page.
After a lot of trial and error I figured out the solution.
All in all you need two different things in your project:
1) A class that inherits from ProminentProjectAction:
import hudson.model.ProminentProjectAction;
public class MyProjectAction implements ProminentProjectAction {
#Override
public String getIconFileName() {
// return the path to the icon file
return "/images/jenkins.png";
}
#Override
public String getDisplayName() {
// return the label for your link
return "MyActionLink";
}
#Override
public String getUrlName() {
// defines the suburl, which is appended to ...jenkins/job/jobname
return "myactionpage";
}
}
2) Even more important is that you add this action somehow to your project.
In my case I wanted to show the link if and only if the related build step of my plugin is configured for the actual project. So I took my Builder class and overwrote the getProjectActionsMethod.
public class MyBuilder extends Builder {
...
#Override
public Collection<? extends Action> getProjectActions(AbstractProject<?,?> project) {
List<Action> actions = new ArrayList<>();
actions.add(new MyProjectAction());
return actions;
}
}
Maybe this is not the perfect solution yet (because I'm still trying to figure out how all the artifacts are working together), but it might give people which want to implement the same a good starting point.
The page, which is loaded after clicking the link is defined as index.jelly file under source/main/resources and an underlying package with the name of the package of your Action class appended by its class name (e.g. src/main/resources/org/example/myplugin/MyProjectAction).
As it happens, there was a plugin workshop by Steven Christou at the recent Jenkins User Conference in Boston, which covered this case. You need to add a new RootAction, as shown in the following code from the JUC session
package org.jenkinsci.plugins.JUCBeer;
import hudson.Extension;
import hudson.model.RootAction;
#Extension
public class JenkinsRootAction implements RootAction {
public String getIconFileName() {
return "/images/jenkins.png";
}
public String getDisplayName() {
return "Jenkins home page";
}
public String getUrlName() {
return "http://jenkins-ci.org";
}
}
https://github.com/jenkinsci/s3explorer-plugin is my Jenkins plugin that adds an S3 Explorer link to all Jenkins project's side-panel.
An addition to #dchang comment:
I managed to make this functionality work also on pipelines by extending TransientActionFactory<WorkflowJob>:
#Extension
public static class PipelineLatestConsoleProjectActionFactory extends TransientActionFactory<WorkflowJob> {
#Override
public Class<WorkflowJob> type() {
return WorkflowJob.class;
}
#Nonnull
#Override
public Collection<? extends Action> createFor(#Nonnull WorkflowJob job) {
return Collections.singletonList(new LatestConsoleProjectAction(job));
}
}

Timer events in ASP.NET MVC

Problem: user operates over some entity in a domain. The last one changes its status so that user recieves e-mail notifications (using smtp server) repeatedly until the given time.
So I need to fire an event somehow.
What are the alternative ways to do that? I know there're no events in ASP.NET MVC framework.
Thanks!
You can use my Inversion Of Control container which has built in support for in-process domain events:
Subscribing
Subscribing is easy. Simply let any class implement IHandlerOf:
[Component]
public class ReplyEmailNotification : IHandlerOf<ReplyPosted>
{
ISmtpClient _client;
IUserQueries _userQueries;
public ReplyEmailNotification(ISmtpClient client, IUserQueries userQueries)
{
_client = client;
_userQueries = userQueries;
}
public void Invoke(ReplyPosted e)
{
var user = _userQueries.Get(e.PosterId);
_client.Send(new MailMessage(user.Email, "bla bla"));
}
}
Dispatching
Domain events are dispatched using the DomainEvent class. The actual domain event can be any class, there are no restrictions. I do however recommend that you treat them as DTO's.
public class UserCreated
{
public UserCreated(string id, string displayName)
{
}
}
public class UserService
{
public void Create(string displayName)
{
//create user
// [...]
// fire the event.
DomainEvent.Publish(new UserCreated(user.Id, user.DisplayName));
}
}
The code is from my article: http://www.codeproject.com/Articles/440665/Having-fun-with-Griffin-Container
ASP.NET MVC3 installation:
Use package manager console: install-package griffin.container.mvc3
Follow these instructions: http://griffinframework.net/docs/container/mvc3/

Resources