diff options
9 files changed, 308 insertions, 8 deletions
diff --git a/src/org/traccar/web/client/controller/SettingsController.java b/src/org/traccar/web/client/controller/SettingsController.java index a1892ae2..f8fcc72d 100644 --- a/src/org/traccar/web/client/controller/SettingsController.java +++ b/src/org/traccar/web/client/controller/SettingsController.java @@ -15,17 +15,27 @@ */ package org.traccar.web.client.controller; +import java.util.List; + import org.traccar.web.client.Application; import org.traccar.web.client.ApplicationContext; import org.traccar.web.client.model.BaseAsyncCallback; +import org.traccar.web.client.model.UserProperties; import org.traccar.web.client.view.ApplicationSettingsDialog; import org.traccar.web.client.view.DeviceView; import org.traccar.web.client.view.UserDialog; import org.traccar.web.client.view.UserSettingsDialog; +import org.traccar.web.client.view.UsersDialog; import org.traccar.web.shared.model.ApplicationSettings; import org.traccar.web.shared.model.User; import org.traccar.web.shared.model.UserSettings; +import com.google.gwt.core.client.GWT; +import com.sencha.gxt.data.shared.ListStore; +import com.sencha.gxt.widget.core.client.Dialog.PredefinedButton; +import com.sencha.gxt.widget.core.client.box.ConfirmMessageBox; +import com.sencha.gxt.widget.core.client.event.HideEvent; + public class SettingsController implements DeviceView.SettingsHandler { @Override @@ -66,8 +76,54 @@ public class SettingsController implements DeviceView.SettingsHandler { @Override public void onUsersSelected() { - // TODO Auto-generated method stub + Application.getDataService().getUsers(new BaseAsyncCallback<List<User>>() { + @Override + public void onSuccess(List<User> result) { + UserProperties userProperties = GWT.create(UserProperties.class); + final ListStore<User> userStore = new ListStore<User>(userProperties.id()); + userStore.addAll(result); + new UsersDialog(userStore, new UsersDialog.UserHandler() { + + @Override + public void onAdd() { + new UserDialog( + new User(), + new UserDialog.UserHandler() { + @Override + public void onSave(User user) { + Application.getDataService().addUser(user, new BaseAsyncCallback<User>() { + @Override + public void onSuccess(User result) { + userStore.add(result); + } + }); + } + }).show(); + } + + @Override + public void onRemove(final User user) { + final ConfirmMessageBox dialog = new ConfirmMessageBox("Confirm", "Are you sure you want remove user?"); + dialog.addHideHandler(new HideEvent.HideHandler() { + @Override + public void onHide(HideEvent event) { + if (dialog.getHideButton() == dialog.getButtonById(PredefinedButton.YES.name())) { + Application.getDataService().removeUser(user, new BaseAsyncCallback<User>() { + @Override + public void onSuccess(User result) { + userStore.remove(user); + } + }); + } + } + }); + dialog.show(); + } + + }).show(); + } + }); } @Override diff --git a/src/org/traccar/web/client/model/DataService.java b/src/org/traccar/web/client/model/DataService.java index 3e649717..2bb78832 100644 --- a/src/org/traccar/web/client/model/DataService.java +++ b/src/org/traccar/web/client/model/DataService.java @@ -37,8 +37,14 @@ public interface DataService extends RemoteService { User register(String login, String password); + List<User> getUsers(); + + User addUser(User user); + User updateUser(User user); + User removeUser(User user); + List<Device> getDevices(); Device addDevice(Device device); diff --git a/src/org/traccar/web/client/model/DataServiceAsync.java b/src/org/traccar/web/client/model/DataServiceAsync.java index 559545d9..b1830639 100644 --- a/src/org/traccar/web/client/model/DataServiceAsync.java +++ b/src/org/traccar/web/client/model/DataServiceAsync.java @@ -35,8 +35,14 @@ public interface DataServiceAsync { void register(String login, String password, AsyncCallback<User> callback); + void getUsers(AsyncCallback<List<User>> callback); + + void addUser(User user, AsyncCallback<User> callback); + void updateUser(User user, AsyncCallback<User> callback); + void removeUser(User user, AsyncCallback<User> callback); + void getDevices(AsyncCallback<List<Device>> callback); void addDevice(Device device, AsyncCallback<Device> callback); diff --git a/src/org/traccar/web/client/view/DeviceView.java b/src/org/traccar/web/client/view/DeviceView.java index 341b5083..21d906c8 100644 --- a/src/org/traccar/web/client/view/DeviceView.java +++ b/src/org/traccar/web/client/view/DeviceView.java @@ -19,6 +19,7 @@ import java.util.LinkedList; import java.util.List; import org.traccar.web.client.Application; +import org.traccar.web.client.ApplicationContext; import org.traccar.web.client.model.BaseAsyncCallback; import org.traccar.web.client.model.DeviceProperties; import org.traccar.web.shared.model.Device; @@ -39,6 +40,7 @@ import com.sencha.gxt.widget.core.client.grid.ColumnConfig; import com.sencha.gxt.widget.core.client.grid.ColumnModel; import com.sencha.gxt.widget.core.client.grid.Grid; import com.sencha.gxt.widget.core.client.menu.Item; +import com.sencha.gxt.widget.core.client.menu.MenuItem; import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent; public class DeviceView implements SelectionChangedEvent.SelectionChangedHandler<Device> { @@ -82,6 +84,12 @@ public class DeviceView implements SelectionChangedEvent.SelectionChangedHandler @UiField Grid<Device> grid; + @UiField + MenuItem settingsUsers; + + @UiField + MenuItem settingsGlobal; + public DeviceView(DeviceHandler deviceHandler, SettingsHandler settingsHandler, ListStore<Device> deviceStore) { this.deviceHandler = deviceHandler; this.settingsHandler = settingsHandler; @@ -98,6 +106,11 @@ public class DeviceView implements SelectionChangedEvent.SelectionChangedHandler grid.getSelectionModel().addSelectionChangedHandler(this); grid.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); + + if (ApplicationContext.getInstance().getUser().getAdmin()) { + settingsUsers.enable(); + settingsGlobal.enable(); + } } @Override @@ -155,17 +168,17 @@ public class DeviceView implements SelectionChangedEvent.SelectionChangedHandler settingsHandler.onAccountSelected(); } - @UiHandler("preferencesAccount") + @UiHandler("settingsPreferences") public void onSettingsPreferencesSelected(SelectionEvent<Item> event) { settingsHandler.onPreferencesSelected(); } - @UiHandler("usersAccount") + @UiHandler("settingsUsers") public void onSettingsUsersSelected(SelectionEvent<Item> event) { settingsHandler.onUsersSelected(); } - @UiHandler("globalAccount") + @UiHandler("settingsGlobal") public void onSettingsGlobalSelected(SelectionEvent<Item> event) { settingsHandler.onApplicationSelected(); } diff --git a/src/org/traccar/web/client/view/DeviceView.ui.xml b/src/org/traccar/web/client/view/DeviceView.ui.xml index f612957d..38721ca0 100644 --- a/src/org/traccar/web/client/view/DeviceView.ui.xml +++ b/src/org/traccar/web/client/view/DeviceView.ui.xml @@ -37,9 +37,9 @@ <button:menu> <menu:Menu> <menu:MenuItem text="Account" ui:field="settingsAccount" /> - <menu:MenuItem text="Preferences" ui:field="preferencesAccount" /> - <menu:MenuItem text="Users" ui:field="usersAccount" /> - <menu:MenuItem text="Global" ui:field="globalAccount" /> + <menu:MenuItem text="Preferences" ui:field="settingsPreferences" /> + <menu:MenuItem text="Users" ui:field="settingsUsers" enabled="false" /> + <menu:MenuItem text="Global" ui:field="settingsGlobal" enabled="false" /> </menu:Menu> </button:menu> </button:TextButton> diff --git a/src/org/traccar/web/client/view/UsersDialog.java b/src/org/traccar/web/client/view/UsersDialog.java new file mode 100644 index 00000000..3da8979b --- /dev/null +++ b/src/org/traccar/web/client/view/UsersDialog.java @@ -0,0 +1,110 @@ +/* + * Copyright 2013 Anton Tananaev (anton.tananaev@gmail.com) + * + * 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.traccar.web.client.view; + +import java.util.LinkedList; +import java.util.List; + +import org.traccar.web.client.model.UserProperties; +import org.traccar.web.shared.model.User; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.uibinder.client.UiHandler; +import com.google.gwt.user.client.ui.Widget; +import com.sencha.gxt.core.client.Style.SelectionMode; +import com.sencha.gxt.data.shared.ListStore; +import com.sencha.gxt.widget.core.client.Window; +import com.sencha.gxt.widget.core.client.button.TextButton; +import com.sencha.gxt.widget.core.client.event.SelectEvent; +import com.sencha.gxt.widget.core.client.grid.ColumnConfig; +import com.sencha.gxt.widget.core.client.grid.ColumnModel; +import com.sencha.gxt.widget.core.client.grid.Grid; +import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent; + +public class UsersDialog implements SelectionChangedEvent.SelectionChangedHandler<User> { + + private static UsersDialogUiBinder uiBinder = GWT.create(UsersDialogUiBinder.class); + + interface UsersDialogUiBinder extends UiBinder<Widget, UsersDialog> { + } + + public interface UserHandler { + public void onAdd(); + public void onRemove(User user); + } + + private UserHandler userHandler; + + @UiField + Window window; + + @UiField + TextButton addButton; + + @UiField + TextButton removeButton; + + @UiField(provided = true) + ColumnModel<User> columnModel; + + @UiField(provided = true) + ListStore<User> userStore; + + @UiField + Grid<User> grid; + + public UsersDialog(ListStore<User> userStore, UserHandler userHandler) { + this.userStore = userStore; + this.userHandler = userHandler; + + UserProperties userProperties = GWT.create(UserProperties.class); + + List<ColumnConfig<User, ?>> columnConfigList = new LinkedList<ColumnConfig<User, ?>>(); + columnConfigList.add(new ColumnConfig<User, String>(userProperties.login(), 0, "Name")); + columnConfigList.add(new ColumnConfig<User, Boolean>(userProperties.admin(), 0, "Administrator")); + columnModel = new ColumnModel<User>(columnConfigList); + + uiBinder.createAndBindUi(this); + + grid.getSelectionModel().addSelectionChangedHandler(this); + grid.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); + } + + public void show() { + window.show(); + } + + public void hide() { + window.hide(); + } + + @Override + public void onSelectionChanged(SelectionChangedEvent<User> event) { + removeButton.setEnabled(!event.getSelection().isEmpty()); + } + @UiHandler("addButton") + public void onAddClicked(SelectEvent event) { + userHandler.onAdd(); + } + + @UiHandler("removeButton") + public void onRemoveClicked(SelectEvent event) { + userHandler.onRemove(grid.getSelectionModel().getSelectedItem()); + } + +} diff --git a/src/org/traccar/web/client/view/UsersDialog.ui.xml b/src/org/traccar/web/client/view/UsersDialog.ui.xml new file mode 100644 index 00000000..2110e760 --- /dev/null +++ b/src/org/traccar/web/client/view/UsersDialog.ui.xml @@ -0,0 +1,50 @@ +<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> +<ui:UiBinder + xmlns:ui="urn:ui:com.google.gwt.uibinder" + xmlns:g="urn:import:com.google.gwt.user.client.ui" + xmlns:gxt="urn:import:com.sencha.gxt.widget.core.client" + xmlns:container="urn:import:com.sencha.gxt.widget.core.client.container" + xmlns:form="urn:import:com.sencha.gxt.widget.core.client.form" + xmlns:toolbar="urn:import:com.sencha.gxt.widget.core.client.toolbar" + xmlns:grid="urn:import:com.sencha.gxt.widget.core.client.grid" + xmlns:button="urn:import:com.sencha.gxt.widget.core.client.button" + xmlns:menu="urn:import:com.sencha.gxt.widget.core.client.menu"> + + <ui:with type="com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData" field="toolBarRowData"> + <ui:attributes width="1" height="-1" /> + </ui:with> + <ui:with type="com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData" field="layoutData"> + <ui:attributes width="1" height="1" /> + </ui:with> + + <ui:with type="com.sencha.gxt.data.shared.ListStore" field="userStore" /> + <ui:with type="com.sencha.gxt.widget.core.client.grid.ColumnModel" field="columnModel" /> + + <ui:with type="com.sencha.gxt.widget.core.client.grid.GridView" field="view"> + <ui:attributes stripeRows="true" autoFill="true" /> + </ui:with> + + <gxt:Window ui:field="window" pixelSize="640, 480" modal="true" headingText="Users"> + <container:VerticalLayoutContainer> + <container:child layoutData="{layoutData}"> + <gxt:ContentPanel ui:field="contentPanel" headerVisible="false"> + <container:VerticalLayoutContainer> + + <container:child layoutData="{toolBarRowData}"> + <toolbar:ToolBar> + <button:TextButton ui:field="addButton" text="Add" /> + <button:TextButton ui:field="removeButton" text="Remove" enabled="false" /> + </toolbar:ToolBar> + </container:child> + + <container:child layoutData="{layoutData}"> + <grid:Grid ui:field="grid" store="{userStore}" cm="{columnModel}" view="{view}" /> + </container:child> + + </container:VerticalLayoutContainer> + </gxt:ContentPanel> + </container:child> + </container:VerticalLayoutContainer> + </gxt:Window> + +</ui:UiBinder> diff --git a/src/org/traccar/web/server/model/DataServiceImpl.java b/src/org/traccar/web/server/model/DataServiceImpl.java index c2d9f72e..663f0e4b 100644 --- a/src/org/traccar/web/server/model/DataServiceImpl.java +++ b/src/org/traccar/web/server/model/DataServiceImpl.java @@ -147,6 +147,41 @@ public class DataServiceImpl extends RemoteServiceServlet implements DataService } @Override + public List<User> getUsers() { + List<User> users = new LinkedList<User>(); + EntityManager entityManager = entityManagerFactory.createEntityManager(); + try { + users.addAll(entityManager.createQuery("SELECT x FROM User x", User.class).getResultList()); + return users; + } finally { + entityManager.close(); + } + } + + @Override + public User addUser(User user) { + User currentUser = getUser(); + if (currentUser.getAdmin()) { + EntityManager entityManager = entityManagerFactory.createEntityManager(); + try { + entityManager.getTransaction().begin(); + try { + entityManager.persist(user); + entityManager.getTransaction().commit(); + return user; + } catch (RuntimeException e) { + entityManager.getTransaction().rollback(); + throw e; + } + } finally { + entityManager.close(); + } + } else { + throw new SecurityException(); + } + } + + @Override public User updateUser(User user) { User currentUser = getUser(); if (currentUser.getAdmin() || (currentUser.getId() == user.getId() && !user.getAdmin())) { @@ -181,6 +216,30 @@ public class DataServiceImpl extends RemoteServiceServlet implements DataService } } + @Override + public User removeUser(User user) { + User currentUser = getUser(); + if (currentUser.getAdmin()) { + EntityManager entityManager = entityManagerFactory.createEntityManager(); + try { + entityManager.getTransaction().begin(); + try { + user = entityManager.merge(user); + entityManager.remove(user); + entityManager.getTransaction().commit(); + return user; + } catch (RuntimeException e) { + entityManager.getTransaction().rollback(); + throw e; + } + } finally { + entityManager.close(); + } + } else { + throw new SecurityException(); + } + } + private void createUser(User user) { EntityManager entityManager = entityManagerFactory.createEntityManager(); try { diff --git a/src/org/traccar/web/shared/model/User.java b/src/org/traccar/web/shared/model/User.java index f94f884e..805c4a6c 100644 --- a/src/org/traccar/web/shared/model/User.java +++ b/src/org/traccar/web/shared/model/User.java @@ -87,7 +87,7 @@ public class User implements Serializable, Cloneable { } @GwtTransient - @OneToMany(fetch = FetchType.EAGER) + @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List<Device> devices = new LinkedList<Device>(); public void setDevices(List<Device> devices) { |