blob: ca2132bd2a71b12615991c089987024d165ba917 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.openmeetings.web.common;
import static org.apache.openmeetings.db.util.AuthLevelUtil.hasAdminLevel;
import static org.apache.openmeetings.db.util.AuthLevelUtil.hasGroupAdminLevel;
import static org.apache.openmeetings.util.OpenmeetingsVariables.PARAM_USER_ID;
import static org.apache.openmeetings.util.OpenmeetingsVariables.isMyRoomsEnabled;
import static org.apache.openmeetings.web.app.WebSession.getUserId;
import static org.apache.openmeetings.web.common.confirmation.ConfirmationHelper.newOkCancelConfirm;
import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getParam;
import static org.apache.openmeetings.web.util.OmUrlFragment.CHILD_ID;
import static org.apache.openmeetings.web.util.OmUrlFragment.getPanel;
import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
import org.apache.openmeetings.db.dao.room.RoomDao;
import org.apache.openmeetings.db.dao.user.UserDao;
import org.apache.openmeetings.db.entity.basic.Client;
import org.apache.openmeetings.db.entity.basic.IWsClient;
import org.apache.openmeetings.db.entity.room.Room;
import org.apache.openmeetings.db.entity.user.PrivateMessage;
import org.apache.openmeetings.db.entity.user.User;
import org.apache.openmeetings.db.entity.user.User.Right;
import org.apache.openmeetings.util.OpenmeetingsVariables;
import org.apache.openmeetings.web.app.Application;
import org.apache.openmeetings.web.app.ClientManager;
import org.apache.openmeetings.web.app.WebSession;
import org.apache.openmeetings.web.common.menu.MainMenuItem;
import org.apache.openmeetings.web.common.menu.MenuPanel;
import org.apache.openmeetings.web.common.menu.OmMenuItem;
import org.apache.openmeetings.web.pages.MainPage;
import org.apache.openmeetings.web.user.AboutDialog;
import org.apache.openmeetings.web.user.InviteUserToRoomDialog;
import org.apache.openmeetings.web.user.MessageDialog;
import org.apache.openmeetings.web.user.UserInfoDialog;
import org.apache.openmeetings.web.user.chat.ChatPanel;
import org.apache.openmeetings.web.user.rooms.RoomEnterBehavior;
import org.apache.openmeetings.web.util.ContactsHelper;
import org.apache.openmeetings.web.util.ExtendedClientProperties;
import org.apache.openmeetings.web.util.OmUrlFragment;
import org.apache.openmeetings.web.util.OmUrlFragment.MenuActions;
import org.apache.openmeetings.web.util.ProfileImageResourceReference;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
import org.apache.wicket.devutils.debugbar.DebugBar;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.markup.head.PriorityHeaderItem;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.panel.EmptyPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.protocol.ws.api.WebSocketRequestHandler;
import org.apache.wicket.protocol.ws.api.message.AbstractClientMessage;
import org.apache.wicket.protocol.ws.api.message.ConnectedMessage;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wicketstuff.urlfragment.UrlFragment;
import com.github.openjson.JSONObject;
import de.agilecoders.wicket.core.markup.html.bootstrap.navbar.INavbarComponent;
import de.agilecoders.wicket.core.markup.html.references.BootstrapJavaScriptReference;
public class MainPanel extends Panel {
private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(MainPanel.class);
private final WebMarkupContainer empty = new WebMarkupContainer(CHILD_ID);
private String uid = null;
private MenuPanel menu;
private final WebMarkupContainer topControls = new WebMarkupContainer("topControls");
private final WebMarkupContainer topLinks = new WebMarkupContainer("topLinks");
private final MarkupContainer contents = new WebMarkupContainer("contents");
private ChatPanel chat;
private MessageDialog newMessage;
private UserInfoDialog userInfo;
private BasePanel curPanel;
private InviteUserToRoomDialog inviteUser;
@SpringBean
private ClientManager cm;
@SpringBean
private ConfigurationDao cfgDao;
@SpringBean
private UserDao userDao;
@SpringBean
private RoomDao roomDao;
public MainPanel(String id) {
this(id, null);
}
public MainPanel(String id, BasePanel curPanel) {
super(id);
this.curPanel = curPanel;
setAuto(true);
setOutputMarkupId(true);
setOutputMarkupPlaceholderTag(true);
}
@Override
protected void onInitialize() {
super.onInitialize();
add(new OmWebSocketPanel("ws-panel") {
private static final long serialVersionUID = 1L;
@Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
StringBuilder handlers = new StringBuilder()
.append("Wicket.Event.subscribe(Wicket.Event.Topic.AJAX_CALL_FAILURE, hideBusyIndicator);")
.append("Wicket.Event.subscribe(Wicket.Event.Topic.AJAX_CALL_BEFORE, showBusyIndicator);")
.append("Wicket.Event.subscribe(Wicket.Event.Topic.AJAX_CALL_SUCCESS, hideBusyIndicator);")
.append("Wicket.Event.subscribe(Wicket.Event.Topic.AJAX_CALL_COMPLETE, hideBusyIndicator);")
.append("Wicket.Event.subscribe(Wicket.Event.Topic.WebSocket.Opened, function() { Wicket.WebSocket.send('socketConnected'); });");
response.render(OnDomReadyHeaderItem.forScript(handlers));
}
@Override
protected void onConnect(ConnectedMessage msg) {
ExtendedClientProperties cp = WebSession.get().getExtendedProperties();
final User u = userDao.get(getUserId());
final Client client = new Client(
getSession().getId()
, msg.getKey().hashCode()
, u
, ProfileImageResourceReference.getUrl(getRequestCycle(), u));
uid = client.getUid();
cm.add(cp.update(client));
log.debug("WebSocketBehavior::onConnect [uid: {}, session: {}, key: {}]", client.getUid(), msg.getSessionId(), msg.getKey());
}
@Override
protected void onConnect(WebSocketRequestHandler handler) {
if (curPanel != null) {
updateContents(curPanel, handler);
}
}
@Override
protected void onMessage(WebSocketRequestHandler handler, JSONObject m) throws IOException {
BasePanel p = getCurrentPanel();
if (p != null) {
p.process(handler, m);
}
}
@Override
protected void closeHandler(AbstractClientMessage msg) {
log.debug("WebSocketBehavior::closeHandler uid - {}", uid);
super.closeHandler(msg);
if (uid != null) {
cm.exit(getClient());
uid = null;
}
}
@Override
protected IWsClient getWsClient() {
return getClient();
}
});
menu = new MenuPanel("menu", getMainMenu());
add(topControls.setOutputMarkupPlaceholderTag(true).setMarkupId("topControls"));
add(contents.add(getClient() == null || curPanel == null ? empty : curPanel).setOutputMarkupId(true).setMarkupId("contents"));
topControls.add(menu.setVisible(false), topLinks.setVisible(false).setOutputMarkupPlaceholderTag(true).setMarkupId("topLinks"));
final AboutDialog about = new AboutDialog("aboutDialog");
topLinks.add(new AjaxLink<Void>("about") {
private static final long serialVersionUID = 1L;
@Override
public void onClick(AjaxRequestTarget target) {
about.show(target);
}
});
if (getApplication().getDebugSettings().isDevelopmentUtilitiesEnabled()) {
add(new DebugBar("dev").setOutputMarkupId(true));
} else {
add(new EmptyPanel("dev").setVisible(false));
}
add(new OmAjaxClientInfoBehavior());
add(about, chat = new ChatPanel("chatPanel"));
add(newMessage = new MessageDialog("newMessageDialog", new CompoundPropertyModel<>(new PrivateMessage())) {
private static final long serialVersionUID = 1L;
@Override
public void onSend(IPartialPageRequestHandler handler) {
BasePanel bp = getCurrentPanel();
if (bp != null) {
bp.onNewMessageClose(handler);
}
}
});
add(userInfo = new UserInfoDialog("userInfoDialog", newMessage));
add(new AbstractDefaultAjaxBehavior() {
private static final long serialVersionUID = 1L;
@Override
protected void respond(AjaxRequestTarget target) {
userInfo.show(target, getParam(getComponent(), PARAM_USER_ID).toLong());
}
@Override
public void renderHead(Component component, IHeaderResponse response) {
super.renderHead(component, response);
response.render(new PriorityHeaderItem(getNamedFunction("showUserInfo", this, explicit(PARAM_USER_ID))));
}
});
add(new AbstractDefaultAjaxBehavior() {
private static final long serialVersionUID = 1L;
@Override
protected void respond(AjaxRequestTarget target) {
ContactsHelper.addUserToContactList(getParam(getComponent(), PARAM_USER_ID).toLong());
}
@Override
public void renderHead(Component component, IHeaderResponse response) {
super.renderHead(component, response);
response.render(new PriorityHeaderItem(getNamedFunction("addContact", this, explicit(PARAM_USER_ID))));
}
});
add(new AbstractDefaultAjaxBehavior() {
private static final long serialVersionUID = 1L;
@Override
protected void respond(AjaxRequestTarget target) {
newMessage.reset(true).show(target, getParam(getComponent(), PARAM_USER_ID).toOptionalLong());
}
@Override
public void renderHead(Component component, IHeaderResponse response) {
super.renderHead(component, response);
response.render(new PriorityHeaderItem(getNamedFunction("privateMessage", this, explicit(PARAM_USER_ID))));
}
});
add(inviteUser = new InviteUserToRoomDialog("invite-to-room"));
add(new AbstractDefaultAjaxBehavior() {
private static final long serialVersionUID = 1L;
@Override
protected void respond(AjaxRequestTarget target) {
inviteUser.show(target, getParam(getComponent(), PARAM_USER_ID).toLong());
}
@Override
public void renderHead(Component component, IHeaderResponse response) {
super.renderHead(component, response);
response.render(new PriorityHeaderItem(getNamedFunction("inviteUser", this, explicit(PARAM_USER_ID))));
}
});
AjaxLink<Void> logout = new AjaxLink<>("logout") {
private static final long serialVersionUID = 1L;
@Override
public void onClick(AjaxRequestTarget target) {
getSession().invalidate();
setResponsePage(Application.get().getSignInPageClass());
}
};
logout.add(newOkCancelConfirm(this, getString("634")));
topLinks.add(logout);
}
@Override
public void renderHead(IHeaderResponse response) {
response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(BootstrapJavaScriptReference.instance()))); //this one should go before jquery-ui
super.renderHead(response);
}
private OmMenuItem getSubItem(String lbl, String title, MenuActions action) {
return new MainMenuItem(lbl, title, action) {
private static final long serialVersionUID = 1L;
@Override
public void onClick(AjaxRequestTarget target) {
onClick(MainPanel.this, target);
}
};
}
private List<INavbarComponent> getMainMenu() {
List<INavbarComponent> mmenu = new ArrayList<>();
createDashboardMenu(mmenu);
createRoomsMenu(mmenu);
if (OpenmeetingsVariables.isRecordingsEnabled()) {
// Recording Menu Points
mmenu.add(getSubItem("395", "1452", MenuActions.RECORD));
}
createSettingsMenu(mmenu);
Set<Right> r = WebSession.getRights();
if (r.stream().anyMatch(right -> right.name().contains("ADMIN"))) {
boolean isAdmin = hasAdminLevel(r);
boolean isGrpAdmin = hasGroupAdminLevel(r);
// Administration Menu Points
List<INavbarComponent> l = new ArrayList<>();
if (isAdmin || isGrpAdmin) {
l.add(getSubItem("125", "1454", MenuActions.ADMIN_USER));
}
if (isAdmin || r.contains(Right.ADMIN_CONNECTIONS)) {
l.add(getSubItem("597", "1455", MenuActions.ADMIN_CONNECTION));
}
if (isAdmin || isGrpAdmin) {
l.add(getSubItem("126", "1456", MenuActions.ADMIN_GROUP));
l.add(getSubItem("186", "1457", MenuActions.ADMIN_ROOM));
}
if (isAdmin || r.contains(Right.ADMIN_CONFIG)) {
l.add(getSubItem("263", "1458", MenuActions.ADMIN_CONFIG));
}
if (isAdmin || r.contains(Right.ADMIN_LABEL)) {
l.add(getSubItem("348", "1459", MenuActions.ADMIN_LABEL));
}
if (isAdmin) {
l.add(getSubItem("1103", "1454", MenuActions.ADMIN_LDAP));
l.add(getSubItem("1571", "1572", MenuActions.ADMIN_OAUTH));
}
if (isAdmin || r.contains(Right.ADMIN_BACKUP)) {
l.add(getSubItem("367", "1461", MenuActions.ADMIN_BACKUP));
}
if (isAdmin) {
l.add(getSubItem("main.menu.admin.email", "main.menu.admin.email.desc", MenuActions.ADMIN_EMAIL));
}
if (isAdmin || isGrpAdmin) {
l.add(getSubItem("main.menu.admin.extra", "main.menu.admin.extra.desc", MenuActions.ADMIN_EXTRA));
}
mmenu.add(new OmMenuItem(getString("6"), l));
}
return mmenu;
}
private void createDashboardMenu(List<INavbarComponent> mmenu) {
List<INavbarComponent> l = new ArrayList<>();
l.add(getSubItem("290", "1450", MenuActions.DASHBOARD_START));
l.add(getSubItem("291", "1451", MenuActions.DASHBOARD_CALENDAR));
mmenu.add(new OmMenuItem(getString("124"), l));
}
private void createRoomsMenu(List<INavbarComponent> mmenu) {
List<INavbarComponent> l = new ArrayList<>();
l.add(getSubItem("777", "1506", MenuActions.ROOMS_PUBLIC));
l.add(getSubItem("779", "1507", MenuActions.ROOMS_GROUP));
if (isMyRoomsEnabled()) {
l.add(getSubItem("781", "1508", MenuActions.ROOMS_MY));
}
List<Room> recent = roomDao.getRecent(getUserId());
if (!recent.isEmpty()) {
l.add(new OmMenuItem(null, (String)null));
}
for (Room r : recent) {
final Long roomId = r.getId();
l.add(new OmMenuItem(r.getName(), r.getName()) {
private static final long serialVersionUID = 1L;
@Override
protected void onClick(AjaxRequestTarget target) {
RoomEnterBehavior.roomEnter((MainPage)getPage(), target, roomId);
}
});
}
mmenu.add(new OmMenuItem(getString("792"), l));
}
private void createSettingsMenu(List<INavbarComponent> mmenu) {
List<INavbarComponent> l = new ArrayList<>();
l.add(getSubItem("1188", "1188", MenuActions.PROFILE_MESSAGE));
l.add(getSubItem("377", "377", MenuActions.PROFILE_EDIT));
l.add(getSubItem("1172", "1172", MenuActions.PROFILE_SEARCH));
l.add(getSubItem("profile.invitations", "profile.invitations", MenuActions.PROFILE_INVITATION));
l.add(getSubItem("1548", "1548", MenuActions.PROFILE_WIDGET));
mmenu.add(new OmMenuItem(getString("4"), l));
}
public void updateContents(OmUrlFragment f, IPartialPageRequestHandler handler) {
updateContents(f, handler, true);
}
private BasePanel getCurrentPanel() {
Component prev = contents.get(CHILD_ID);
if (prev instanceof BasePanel basePrev) {
return basePrev;
}
return null;
}
public void updateContents(OmUrlFragment f, IPartialPageRequestHandler handler, boolean updateFragment) {
BasePanel npanel = getPanel(f.getArea(), f.getType());
log.debug("updateContents:: npanels IS null ? {}, client IS null ? {}", npanel == null, getClient() == null);
if (npanel != null) {
if (getClient() != null) {
updateContents(npanel, handler);
} else {
this.curPanel = npanel;
}
if (updateFragment) {
UrlFragment uf = new UrlFragment(handler);
uf.set(f.getArea().name(), f.getType());
}
}
}
private void updateContents(BasePanel inPanel, IPartialPageRequestHandler handler) {
if (inPanel != null) {
BasePanel prev = getCurrentPanel();
if (prev != null) {
prev.cleanup(handler);
}
handler.add(contents.replace(inPanel));
handler.appendJavaScript("$('#" + this.getMarkupId() + "').attr('class', 'main " + inPanel.getCssClass() + "');");
inPanel.onMenuPanelLoad(handler);
}
}
public MenuPanel getMenu() {
return menu;
}
public WebMarkupContainer getTopLinks() {
return topLinks;
}
public WebMarkupContainer getTopControls() {
return topControls;
}
public ChatPanel getChat() {
return chat;
}
public MessageDialog getMessageDialog() {
return newMessage;
}
public String getUid() {
return uid;
}
public Client getClient() {
return cm.get(uid);
}
}