/*
* Copyright 2010 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.guvnor.client.ruleeditor;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.drools.guvnor.client.common.GenericCallback;
import org.drools.guvnor.client.common.SmallLabel;
import org.drools.guvnor.client.messages.Constants;
import org.drools.guvnor.client.resources.Images;
import org.drools.guvnor.client.rpc.DiscussionRecord;
import org.drools.guvnor.client.rpc.PushClient;
import org.drools.guvnor.client.rpc.PushResponse;
import org.drools.guvnor.client.rpc.RepositoryServiceFactory;
import org.drools.guvnor.client.rpc.RuleAsset;
import org.drools.guvnor.client.rpc.ServerPushNotification;
import org.drools.guvnor.client.security.Capabilities;
import org.drools.guvnor.client.security.CapabilitiesManager;
import org.drools.guvnor.client.util.DecoratedDisclosurePanel;
import org.drools.guvnor.client.util.Format;
import org.drools.guvnor.client.util.Util;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
/**
*
* Does the discussion panel for assets.
*
* @author Michael Neale
*/
public class DiscussionWidget extends Composite {
private static Constants constants = GWT.create( Constants.class );
private static Images images = GWT.create( Images.class );
private VerticalPanel commentList = new VerticalPanel();
private VerticalPanel newCommentLayout = new VerticalPanel();
private RuleAsset asset;
private ServerPushNotification pushNotify;
private int lastCount = 0;
@Override
protected void onUnload() {
super.onUnload(); //To change body of overridden methods use File | Settings | File Templates.
PushClient.instance().unsubscribe( pushNotify );
}
public DiscussionWidget(final RuleAsset asset) {
this.asset = asset;
DecoratedDisclosurePanel discussionPanel = new DecoratedDisclosurePanel( constants.Discussion() );
discussionPanel.setWidth( "100%" );
commentList.setWidth( "100%" );
VerticalPanel discussionLayout = new VerticalPanel();
discussionLayout.setWidth( "90%" );
discussionLayout.add( commentList );
newCommentLayout.setWidth( "100%" );
refreshDiscussion();
discussionLayout.add( newCommentLayout );
showNewCommentButton();
discussionPanel.setContent( discussionLayout );
pushNotify = new ServerPushNotification() {
public void messageReceived(PushResponse response) {
if ( "discussion".equals( response.messageType ) && asset.uuid.equals( response.message ) ) {
System.err.println( "Refreshing discussion..." );
refreshDiscussion();
}
}
};
PushClient.instance().subscribe( pushNotify );
initWidget( discussionPanel );
}
/** Hit up the server */
public void refreshDiscussion() {
RepositoryServiceFactory.getService().loadDiscussionForAsset( asset.uuid,
new GenericCallback<List<DiscussionRecord>>() {
public void onSuccess(List<DiscussionRecord> result) {
updateCommentList( result );
}
} );
}
private void updateCommentList(List<DiscussionRecord> ls) {
if ( ls.size() == lastCount ) return; //don't want to over do it boys...
commentList.clear();
for ( DiscussionRecord dr : ls ) {
appendComment( dr );
}
lastCount = ls.size();
}
private Widget appendComment(DiscussionRecord r) {
SmallLabel hrd = new SmallLabel( Format.format( constants.smallCommentBy0On1Small(),
r.author,
new Date( r.timestamp ).toString() ) );
hrd.addStyleName( "discussion-header" );
commentList.add( hrd );
String[] parts = r.note.split( "\n" );
if ( parts.length > 0 ) {
String txt = "";
for ( int i = 0; i < parts.length; i++ ) {
txt += parts[i];
if ( i != parts.length - 1 ) {
txt += "<br/>";
}
}
HTML hth = new HTML( txt );
hth.setStyleName( "x-form-field" );
commentList.add( hth );
} else {
Label lbl = new Label( r.note );
lbl.setStyleName( "x-form-field" );
commentList.add( lbl );
}
commentList.add( new HTML( "<br/>" ) );
return hrd;
}
private void showNewCommentButton() {
newCommentLayout.clear();
HorizontalPanel hp = new HorizontalPanel();
Button createNewComment = new Button( constants.AddADiscussionComment() );
hp.add( createNewComment );
if ( CapabilitiesManager.getInstance().shouldShow( Capabilities.SHOW_ADMIN ) ) {
Button adminClearAll = new Button( constants.EraseAllComments() );
hp.add( adminClearAll );
adminClearAll.addClickHandler( new ClickHandler() {
public void onClick(ClickEvent sender) {
if ( Window.confirm( constants.EraseAllCommentsWarning() ) ) {
RepositoryServiceFactory.getService().clearAllDiscussionsForAsset( asset.uuid,
new GenericCallback<java.lang.Void>() {
public void onSuccess(Void v) {
updateCommentList( new ArrayList<DiscussionRecord>() );
}
} );
}
}
} );
}
String feedURL = Format.format( "{0}feed/discussion?package={1}&assetName={2}&viewUrl={3}",
GWT.getModuleBaseURL(),
asset.metaData.packageName,
URL.encode( asset.metaData.name ),
Util.getSelfURL() );
hp.add( new HTML( Format.format( "<a href='{0}' target='_blank'><img src='{1}'/></a>",
feedURL,
new Image( images.feed() ).getUrl() ) ) );
newCommentLayout.add( hp );
newCommentLayout.setCellHorizontalAlignment( hp,
HasHorizontalAlignment.ALIGN_RIGHT );
createNewComment.addClickHandler( new ClickHandler() {
public void onClick(ClickEvent sender) {
showAddNewComment();
}
} );
}
private void showAddNewComment() {
newCommentLayout.clear();
final TextArea comment = new TextArea();
comment.setWidth( "100%" );
newCommentLayout.add( comment );
Button ok = new Button( constants.OK() );
Button cancel = new Button( constants.Cancel() );
ok.addClickHandler( new ClickHandler() {
public void onClick(ClickEvent sender) {
sendNewComment( comment.getText() );
}
} );
cancel.addClickHandler( new ClickHandler() {
public void onClick(ClickEvent sender) {
showNewCommentButton();
}
} );
HorizontalPanel hp = new HorizontalPanel();
hp.add( ok );
hp.add( cancel );
newCommentLayout.add( hp );
comment.setFocus( true );
}
private void sendNewComment(String text) {
newCommentLayout.clear();
newCommentLayout.add( new Image( images.spinner() ) );
RepositoryServiceFactory.getService().addToDiscussionForAsset( asset.uuid,
text,
new GenericCallback<List<DiscussionRecord>>() {
public void onSuccess(List<DiscussionRecord> result) {
showNewCommentButton();
updateCommentList( result );
}
} );
}
}