Shubhendu Tripathi has uploaded a new change for review. Change subject: webadmin: UI for gluster volume snapshot creation ......................................................................
webadmin: UI for gluster volume snapshot creation Introduced UI dialog for gluster volume snapshot creation and scheduling snapshots. Change-Id: I823580ecb127e48e075c437668bfb19ff8ec4467 Signed-off-by: Shubhendu Tripathi <[email protected]> --- A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GetGlusterVolumeSnapshotScheduleByVolumeIdQuery.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterQueriesCommandBase.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotListModel.java A frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotModel.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java M frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIConstants.java M frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIMessages.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java A frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/GlusterVolumeSnapshotCreatePopupPresenterWidget.java A frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.java A frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.ui.xml M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java 17 files changed, 1,277 insertions(+), 4 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/04/40004/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GetGlusterVolumeSnapshotScheduleByVolumeIdQuery.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GetGlusterVolumeSnapshotScheduleByVolumeIdQuery.java new file mode 100644 index 0000000..ad04a35 --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GetGlusterVolumeSnapshotScheduleByVolumeIdQuery.java @@ -0,0 +1,14 @@ +package org.ovirt.engine.core.bll.gluster; + +import org.ovirt.engine.core.common.queries.IdQueryParameters; + +public class GetGlusterVolumeSnapshotScheduleByVolumeIdQuery<P extends IdQueryParameters> extends GlusterQueriesCommandBase<P> { + public GetGlusterVolumeSnapshotScheduleByVolumeIdQuery(P parameters) { + super(parameters); + } + + @Override + public void executeQueryCommand() { + getQueryReturnValue().setReturnValue(getGlusterVolumeSnapshotScheduleDao().getByVolumeId(getParameters().getId())); + } +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterQueriesCommandBase.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterQueriesCommandBase.java index bcb600c..e08cef6 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterQueriesCommandBase.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterQueriesCommandBase.java @@ -21,6 +21,7 @@ import org.ovirt.engine.core.dao.gluster.GlusterVolumeDao; import org.ovirt.engine.core.dao.gluster.GlusterVolumeSnapshotConfigDao; import org.ovirt.engine.core.dao.gluster.GlusterVolumeSnapshotDao; +import org.ovirt.engine.core.dao.gluster.GlusterVolumeSnapshotScheduleDao; public abstract class GlusterQueriesCommandBase<P extends VdcQueryParametersBase> extends QueriesCommandBase<P> { protected GlusterQueriesCommandBase(P parameters) { @@ -72,6 +73,10 @@ return DbFacade.getInstance().getGlusterVolumeSnapshotConfigDao(); } + protected GlusterVolumeSnapshotScheduleDao getGlusterVolumeSnapshotScheduleDao() { + return DbFacade.getInstance().getGlusterVolumeSnapshotScheduleDao(); + } + protected Guid getUpServerId(Guid clusterId) { VDS vds = getClusterUtils().getUpServer(clusterId); if (vds == null) { diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java index e3593f2..f02f0e4 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java @@ -341,6 +341,7 @@ GetGlusterVolumeSnapshotsByVolumeId, GetGlusterVolumeGeoRepConfigList, GetGlusterVolumeSnapshotConfig, + GetGlusterVolumeSnapshotScheduleByVolumeId, GetDefaultConfigurationVersion(VdcQueryAuthType.User), OsRepository(VdcQueryAuthType.User), diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java index bd8a624..6c18633 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java @@ -1592,6 +1592,18 @@ Frontend.getInstance().runQuery(VdcQueryType.GetGlusterVolumeGeoRepSessions, new IdQueryParameters(masterVolumeId), aQuery); } + public static void getVolumeSnapshotSchedule(AsyncQuery aQuery, Guid volumeId) { + aQuery.converterCallback = new IAsyncConverter() { + @Override + public Object Convert(Object source, AsyncQuery asyncQuery) { + return source; + } + }; + Frontend.getInstance().runQuery(VdcQueryType.GetGlusterVolumeSnapshotScheduleByVolumeId, + new IdQueryParameters(volumeId), + aQuery); + } + public static void getGlusterHook(AsyncQuery aQuery, Guid hookId, boolean includeServerHooks) { aQuery.converterCallback = new IAsyncConverter() { @Override diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java index a882ad4..d8006b8 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java @@ -328,6 +328,10 @@ configure_volume_snapshot_confirmation("configure_volume_snapshot_confirmation", HelpTagType.WEBADMIN, "Configure volume snapshot: confirmation dialog that appears when changing the volume snapshot configuration parameters."), //$NON-NLS-1$ //$NON-NLS-2$ + new_volume_snapshot("new_volume_snapshot", HelpTagType.WEBADMIN, "[gluster] Volumes main tab -> Snapshot -> New"), //$NON-NLS-1$ //$NON-NLS-2$ + + edit_volume_snapshot_schedule("edit_volume_snapshot_schedule", HelpTagType.WEBADMIN, "[gluster] Volumes main tab -> Snapshot -> Edit Schedule"), //$NON-NLS-1$ //$NON-NLS-2$ + parameters("parameters", HelpTagType.UNKNOWN), //$NON-NLS-1$ permissions("permissions", HelpTagType.UNKNOWN), //$NON-NLS-1$ diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotListModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotListModel.java index ba42807..08ecd06 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotListModel.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotListModel.java @@ -1,16 +1,25 @@ package org.ovirt.engine.ui.uicommonweb.models.gluster; +import java.sql.Time; import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.List; import org.ovirt.engine.core.common.action.VdcActionParametersBase; import org.ovirt.engine.core.common.action.VdcActionType; +import org.ovirt.engine.core.common.action.VdcReturnValueBase; +import org.ovirt.engine.core.common.action.gluster.CreateGlusterVolumeSnapshotParameters; import org.ovirt.engine.core.common.action.gluster.GlusterVolumeParameters; import org.ovirt.engine.core.common.action.gluster.GlusterVolumeSnapshotActionParameters; +import org.ovirt.engine.core.common.action.gluster.ScheduleGlusterVolumeSnapshotParameters; import org.ovirt.engine.core.common.businessentities.gluster.GlusterSnapshotStatus; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterStatus; import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity; import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotEntity; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotSchedule; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotScheduleRecurrence; +import org.ovirt.engine.core.compat.DayOfWeek; import org.ovirt.engine.ui.frontend.AsyncQuery; import org.ovirt.engine.ui.frontend.Frontend; import org.ovirt.engine.ui.frontend.INewAsyncCallback; @@ -20,13 +29,36 @@ import org.ovirt.engine.ui.uicommonweb.help.HelpTag; import org.ovirt.engine.ui.uicommonweb.models.ConfirmationModel; import org.ovirt.engine.ui.uicommonweb.models.SearchableListModel; +import org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotModel.EndDateOptions; import org.ovirt.engine.ui.uicompat.ConstantsManager; import org.ovirt.engine.ui.uicompat.FrontendActionAsyncResult; import org.ovirt.engine.ui.uicompat.FrontendMultipleActionAsyncResult; import org.ovirt.engine.ui.uicompat.IFrontendActionAsyncCallback; import org.ovirt.engine.ui.uicompat.IFrontendMultipleActionAsyncCallback; +import org.ovirt.engine.ui.uicompat.UIConstants; public class GlusterVolumeSnapshotListModel extends SearchableListModel { + + private UICommand createSnapshotCommand; + + public UICommand getCreateSnapshotCommand() { + return createSnapshotCommand; + } + + public void setCreateSnapshotCommand(UICommand value) { + this.createSnapshotCommand = value; + } + + private UICommand editSnapshotScheduleCommand; + + public UICommand getEditSnapshotScheduleCommand() { + return this.editSnapshotScheduleCommand; + } + + public void setEditSnapshotScheduleCommand(UICommand command) { + this.editSnapshotScheduleCommand = command; + } + @Override public String getListName() { return "GlusterVolumeSnapshotListModel"; //$NON-NLS-1$ @@ -42,6 +74,8 @@ setDeleteAllSnapshotsCommand(new UICommand("deleteAll", this)); //$NON-NLS-1$ setActivateSnapshotCommand(new UICommand("activate", this)); //$NON-NLS-1$ setDeactivateSnapshotCommand(new UICommand("deactivate", this)); //$NON-NLS-1$ + setCreateSnapshotCommand(new UICommand("createSnapshot", this));//$NON-NLS-1$ + setEditSnapshotScheduleCommand(new UICommand("editSnapshotSchedule", this));//$NON-NLS-1$ } @Override @@ -115,6 +149,8 @@ boolean allowDeleteAll = true; boolean allowActivate = false; boolean allowDeactivate = false; + boolean allowCreateSnapshot = true; + boolean allowEditSnapshotSchedule = false; if (getSelectedItems() == null || getSelectedItems().size() == 0) { allowDelete = false; @@ -128,12 +164,23 @@ } } + if (getEntity() == null || getEntity().getStatus() == GlusterStatus.DOWN) { + allowCreateSnapshot = false; + } + + if (getEntity() != null && getEntity().getStatus() == GlusterStatus.UP && getEntity().getSnapshotScheduled()) { + allowEditSnapshotSchedule = true; + } + getRestoreSnapshotCommand().setIsExecutionAllowed(allowRestore); getDeleteSnapshotCommand().setIsExecutionAllowed(allowDelete); getDeleteAllSnapshotsCommand().setIsExecutionAllowed(allowDeleteAll); getActivateSnapshotCommand().setIsExecutionAllowed(allowActivate); getDeactivateSnapshotCommand().setIsExecutionAllowed(allowDeactivate); + getCreateSnapshotCommand().setIsExecutionAllowed(allowCreateSnapshot); + getEditSnapshotScheduleCommand().setIsExecutionAllowed(allowEditSnapshotSchedule); } + @Override protected void syncSearch() { @@ -179,6 +226,16 @@ onDeactivateSnapshot(); } else if (command.getName().equals("cancelConfirmation")) { //$NON-NLS-1$ setConfirmWindow(null); + } else if (command.equals(getCreateSnapshotCommand())) { + createSnapshot(); + } else if (command.getName().equalsIgnoreCase("onCreateSnapshot")) {//$NON-NLS-1$ + onCreateSnapshot(); + } else if (command.getName().equalsIgnoreCase("cancel")) {//$NON-NLS-1$ + setWindow(null); + } else if (command.equals(getEditSnapshotScheduleCommand())) { + editSnapshotSchedule(); + } else if (command.getName().equalsIgnoreCase("onEditSnapshotSchedule")) {//$NON-NLS-1$ + onEditSnapshotSchedule(); } } @@ -391,4 +448,274 @@ public void setEntity(GlusterVolumeEntity value) { super.setEntity(value); } + + private void createSnapshot() { + if (getWindow() != null) { + return; + } + + GlusterVolumeEntity volumeEntity = getEntity(); + GlusterVolumeSnapshotModel snapshotModel = + new GlusterVolumeSnapshotModel(true, !volumeEntity.getSnapshotScheduled()); + + snapshotModel.setHelpTag(HelpTag.new_volume_snapshot); + snapshotModel.setHashName("new_volume_snapshot"); //$NON-NLS-1$ + snapshotModel.setTitle(ConstantsManager.getInstance().getConstants().createScheduleVolumeSnapshotTitle()); + setWindow(snapshotModel); + + snapshotModel.getClusterName().setEntity(volumeEntity.getVdsGroupName()); + snapshotModel.getVolumeName().setEntity(volumeEntity.getName()); + + UICommand okCommand = UICommand.createDefaultOkUiCommand("onCreateSnapshot", this); //$NON-NLS-1$ + snapshotModel.getCommands().add(okCommand); + + UICommand cancelCommand = UICommand.createCancelUiCommand("cancel", this); //$NON-NLS-1$ + snapshotModel.getCommands().add(cancelCommand); + } + + private void onCreateSnapshot() { + final GlusterVolumeSnapshotModel snapshotModel = (GlusterVolumeSnapshotModel) getWindow(); + + if (!snapshotModel.validate()) { + return; + } + + if (!snapshotModel.isScheduleTabVisible() + || snapshotModel.getRecurrence().getSelectedItem() == GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN) { + createNewSnapshot(snapshotModel); + } else { + scheduleSnapshot(snapshotModel, false); + } + } + + private Time getExecutionTime(GlusterVolumeSnapshotModel model) { + int hours = model.getExecutionTime().getEntity().getHours(); + int minutes = model.getExecutionTime().getEntity().getMinutes(); + + return new Time(hours, minutes, 0); + } + + private void scheduleSnapshot(final GlusterVolumeSnapshotModel snapshotModel, boolean reschedule) { + GlusterVolumeEntity volumeEntity = getEntity(); + + final GlusterVolumeSnapshotSchedule schedule = new GlusterVolumeSnapshotSchedule(); + schedule.setSnapshotNamePrefix(snapshotModel.getSnapshotName().getEntity()); + schedule.setSnapshotDescription(snapshotModel.getDescription().getEntity()); + schedule.setClusterId(volumeEntity.getClusterId()); + schedule.setVolumeId(volumeEntity.getId()); + switch (snapshotModel.getRecurrence().getSelectedItem()) { + case INTERVAL: + schedule.setRecurrence(GlusterVolumeSnapshotScheduleRecurrence.INTERVAL); + schedule.setInterval(Integer.valueOf(snapshotModel.getInterval().getSelectedItem())); + break; + case HOURLY: + schedule.setRecurrence(GlusterVolumeSnapshotScheduleRecurrence.HOURLY); + break; + case DAILY: + schedule.setRecurrence(GlusterVolumeSnapshotScheduleRecurrence.DAILY); + schedule.setExecutionTime(getExecutionTime(snapshotModel)); + break; + case WEEKLY: + schedule.setRecurrence(GlusterVolumeSnapshotScheduleRecurrence.WEEKLY); + schedule.setExecutionTime(getExecutionTime(snapshotModel)); + StringBuilder sb = new StringBuilder(); + for (DayOfWeek day : snapshotModel.getDaysOfTheWeek().getSelectedItem()) { + sb.append(day.name().substring(0, 3)); + sb.append(',');//$NON-NLS-1$ + } + schedule.setDays(sb.toString()); + break; + case MONTHLY: + schedule.setRecurrence(GlusterVolumeSnapshotScheduleRecurrence.MONTHLY); + schedule.setExecutionTime(getExecutionTime(snapshotModel)); + schedule.setDays(snapshotModel.getDaysOfMonth().getSelectedItem()); + break; + } + + Date startAt = snapshotModel.getStartAt().getEntity(); + schedule.setStartDate(startAt); + schedule.setTimeZone(snapshotModel.getTimeZones().getSelectedItem()); + + if (snapshotModel.getEndByOptions().getSelectedItem() == EndDateOptions.NoEndDate) { + schedule.setEndByDate(null); + } else { + schedule.setEndByDate(snapshotModel.getEndDate().getEntity()); + } + + ScheduleGlusterVolumeSnapshotParameters params = + new ScheduleGlusterVolumeSnapshotParameters(schedule, true); + snapshotModel.startProgress(null); + + VdcActionType actionType = null; + if (reschedule) { + actionType = VdcActionType.RescheduleGlusterVolumeSnapshot; + } else { + actionType = VdcActionType.ScheduleGlusterVolumeSnapshot; + } + + Frontend.getInstance().runAction(actionType, + params, + new IFrontendActionAsyncCallback() { + @Override + public void executed(FrontendActionAsyncResult result) { + GlusterVolumeSnapshotListModel localModel = + (GlusterVolumeSnapshotListModel) result.getState(); + localModel.stopProgress(); + localModel.postSnapshotAction(result.getReturnValue()); + } + }, + this); + } + + private void createNewSnapshot(final GlusterVolumeSnapshotModel snapshotModel) { + GlusterVolumeEntity volumeEntity = getEntity(); + + final GlusterVolumeSnapshotEntity snapshot = new GlusterVolumeSnapshotEntity(); + snapshot.setClusterId(volumeEntity.getClusterId()); + snapshot.setSnapshotName(snapshotModel.getSnapshotName().getEntity()); + snapshot.setVolumeId(volumeEntity.getId()); + snapshot.setDescription(snapshotModel.getDescription().getEntity()); + + CreateGlusterVolumeSnapshotParameters parameter = + new CreateGlusterVolumeSnapshotParameters(snapshot, true); + + snapshotModel.startProgress(null); + Frontend.getInstance().runAction(VdcActionType.CreateGlusterVolumeSnapshot, + parameter, + new IFrontendActionAsyncCallback() { + @Override + public void executed(FrontendActionAsyncResult result) { + GlusterVolumeSnapshotListModel localModel = + (GlusterVolumeSnapshotListModel) result.getState(); + localModel.stopProgress(); + localModel.postSnapshotAction(result.getReturnValue()); + } + }, + this); + } + + public void postSnapshotAction(VdcReturnValueBase returnValue) { + if (returnValue != null && returnValue.getSucceeded()) { + setWindow(null); + } + } + + public void editSnapshotSchedule() { + if (getWindow() != null) { + return; + } + + final UIConstants constants = ConstantsManager.getInstance().getConstants(); + + final GlusterVolumeSnapshotModel snapshotModel = + new GlusterVolumeSnapshotModel(true, true); + snapshotModel.setHelpTag(HelpTag.edit_volume_snapshot_schedule); + snapshotModel.setHashName("edit_volume_snapshot_schedule"); //$NON-NLS-1$ + snapshotModel.setTitle(constants.editVolumeSnapshotScheduleTitle()); + setWindow(snapshotModel); + + snapshotModel.startProgress(null); + + AsyncDataProvider.getVolumeSnapshotSchedule(new AsyncQuery(this, new INewAsyncCallback() { + + @Override + public void onSuccess(Object model, Object returnValue) { + if (returnValue == null) { + snapshotModel.setMessage(ConstantsManager.getInstance() + .getConstants() + .unableToFetchVolumeSnapshotSchedule()); + return; + } + GlusterVolumeSnapshotSchedule schedule = (GlusterVolumeSnapshotSchedule) returnValue; + snapshotModel.getSnapshotName().setEntity(schedule.getSnapshotNamePrefix()); + snapshotModel.getDescription().setEntity(schedule.getSnapshotDescription()); + snapshotModel.getRecurrence().setSelectedItem(schedule.getRecurrence()); + if (schedule.getEndByDate() == null) { + snapshotModel.getEndByOptions().setSelectedItem(EndDateOptions.NoEndDate); + } else { + snapshotModel.getEndByOptions().setSelectedItem(EndDateOptions.HasEndDate); + snapshotModel.getEndDate().setEntity(schedule.getEndByDate()); + } + + if (schedule.getRecurrence() == GlusterVolumeSnapshotScheduleRecurrence.DAILY + || schedule.getRecurrence() == GlusterVolumeSnapshotScheduleRecurrence.WEEKLY + || schedule.getRecurrence() == GlusterVolumeSnapshotScheduleRecurrence.MONTHLY) { + snapshotModel.getTimeZones().setSelectedItem(schedule.getTimeZone()); + } + switch (schedule.getRecurrence()) { + case INTERVAL: + snapshotModel.getInterval().setSelectedItem(String.valueOf(schedule.getInterval())); + break; + case HOURLY: + break; + case DAILY: + snapshotModel.getExecutionTime().setEntity(getExecutionTimeValue(schedule)); + break; + case WEEKLY: + List<DayOfWeek> daysList = new ArrayList<DayOfWeek>(); + for (String day : schedule.getDays().split(",")) {//$NON-NLS-1$ + daysList.add(getDayOfWeek(day)); + } + snapshotModel.getDaysOfTheWeek().setSelectedItem(daysList); + snapshotModel.getExecutionTime().setEntity(getExecutionTimeValue(schedule)); + break; + case MONTHLY: + snapshotModel.getDaysOfMonth().setSelectedItem(schedule.getDays()); + snapshotModel.getExecutionTime().setEntity(getExecutionTimeValue(schedule)); + break; + } + + snapshotModel.getStartAt().setEntity(schedule.getStartDate()); + snapshotModel.stopProgress(); + } + + private DayOfWeek getDayOfWeek(String day) { + if ("Sun".equals(day)) {//$NON-NLS-1$ + return DayOfWeek.Sunday; + } else if ("Mon".equals(day)) {//$NON-NLS-1$ + return DayOfWeek.Monday; + } else if ("Tue".equals(day)) {//$NON-NLS-1$ + return DayOfWeek.Tuesday; + } else if ("Wed".equals(day)) {//$NON-NLS-1$ + return DayOfWeek.Wednesday; + } else if ("Thu".equals(day)) {//$NON-NLS-1$ + return DayOfWeek.Thursday; + } else if ("Fri".equals(day)) {//$NON-NLS-1$ + return DayOfWeek.Friday; + } else if ("Sat".equals(day)) {//$NON-NLS-1$ + return DayOfWeek.Saturday; + } else { + return null; + } + } + + private Date getExecutionTimeValue(GlusterVolumeSnapshotSchedule schedule) { + Date dt = new Date(); + dt.setHours(schedule.getExecutionTime().getHours()); + dt.setMinutes(schedule.getExecutionTime().getMinutes()); + + return dt; + } + }), + getEntity().getId()); + + snapshotModel.getClusterName().setEntity(getEntity().getVdsGroupName()); + snapshotModel.getVolumeName().setEntity(getEntity().getName()); + + UICommand okCommand = UICommand.createDefaultOkUiCommand("onEditSnapshotSchedule", this); //$NON-NLS-1$ + snapshotModel.getCommands().add(okCommand); + + UICommand cancelCommand = UICommand.createCancelUiCommand("cancel", this); //$NON-NLS-1$ + snapshotModel.getCommands().add(cancelCommand); + } + + public void onEditSnapshotSchedule() { + final GlusterVolumeSnapshotModel snapshotModel = (GlusterVolumeSnapshotModel) getWindow(); + + if (!snapshotModel.validate()) { + return; + } + + scheduleSnapshot(snapshotModel, true); + } } diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotModel.java new file mode 100644 index 0000000..8f5ebf0 --- /dev/null +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotModel.java @@ -0,0 +1,268 @@ +package org.ovirt.engine.ui.uicommonweb.models.gluster; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Set; + +import org.ovirt.engine.core.common.TimeZoneType; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotScheduleRecurrence; +import org.ovirt.engine.core.compat.DayOfWeek; +import org.ovirt.engine.ui.uicommonweb.models.EntityModel; +import org.ovirt.engine.ui.uicommonweb.models.ListModel; +import org.ovirt.engine.ui.uicommonweb.models.Model; +import org.ovirt.engine.ui.uicommonweb.validation.AsciiNameValidation; +import org.ovirt.engine.ui.uicommonweb.validation.IValidation; +import org.ovirt.engine.ui.uicommonweb.validation.LengthValidation; +import org.ovirt.engine.ui.uicommonweb.validation.NotEmptyValidation; +import org.ovirt.engine.ui.uicompat.ConstantsManager; + +public class GlusterVolumeSnapshotModel extends Model { + private EntityModel<String> dataCenter; + private EntityModel<String> clusterName; + private EntityModel<String> volumeName; + private EntityModel<String> snapshotName; + private EntityModel<String> description; + private ListModel<GlusterVolumeSnapshotScheduleRecurrence> recurrence; + private ListModel<String> interval; + private ListModel<EndDateOptions> endByOptions; + private EntityModel<Date> endDate; + private boolean generalTabVisible; + private boolean scheduleTabVisible; + private ListModel<String> timeZones; + private EntityModel<Date> startAt; + private EntityModel<Date> executionTime; + private ListModel<List<DayOfWeek>> daysOfWeek; + private ListModel<String> daysOfMonth; + + public GlusterVolumeSnapshotModel(boolean generalTabVisible, boolean scheduleTabVisible) { + init(); + setGeneralTabVisible(generalTabVisible); + setScheduleTabVisible(scheduleTabVisible); + } + + private void init() { + setDataCenter(new EntityModel<String>()); + setClusterName(new EntityModel<String>()); + setVolumeName(new EntityModel<String>()); + setSnapshotName(new EntityModel<String>()); + setDescription(new EntityModel<String>()); + setRecurrence(new ListModel<GlusterVolumeSnapshotScheduleRecurrence>()); + setInterval(new ListModel<String>()); + setEndByOptions(new ListModel<EndDateOptions>()); + setTimeZones(new ListModel<String>()); + setDaysOfMonth(new ListModel<String>()); + setStartAt(new EntityModel<Date>(new Date())); + setEndDate(new EntityModel<Date>(new Date())); + setExecutionTime(new EntityModel<Date>(new Date())); + initIntervals(); + initTimeZones(); + + recurrence.setItems(Arrays.asList(GlusterVolumeSnapshotScheduleRecurrence.values()), + GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN); + endByOptions.setItems(Arrays.asList(EndDateOptions.values())); + + List<String> values = new ArrayList<String>(); + for (DayOfWeek day : DayOfWeek.values()) { + values.add(day.toString().substring(0, 3)); + } + daysOfWeek = new ListModel<List<DayOfWeek>>(); + List<DayOfWeek> daysList = Arrays.asList(DayOfWeek.values()); + List<List<DayOfWeek>> list = new ArrayList<List<DayOfWeek>>(); + list.add(daysList); + daysOfWeek.setItems(list, new ArrayList<DayOfWeek>()); + } + + private void initIntervals() { + List<String> intervals = new ArrayList<String>(); + int mins = 0; + for (int nThMin = 1; mins < 55; nThMin++) { + mins = nThMin * 5; + intervals.add(String.valueOf(mins)); + } + getInterval().setItems(intervals); + } + + private void initTimeZones() { + Set<String> timeZoneTypes = TimeZoneType.GENERAL_TIMEZONE.getTimeZoneList().keySet(); + getTimeZones().setItems(timeZoneTypes); + } + + public EntityModel<String> getDataCenter() { + return this.dataCenter; + } + + public void setDataCenter(EntityModel<String> dataCenter) { + this.dataCenter = dataCenter; + } + + public EntityModel<String> getClusterName() { + return clusterName; + } + + public void setClusterName(EntityModel<String> clusterName) { + this.clusterName = clusterName; + } + + public EntityModel<String> getVolumeName() { + return volumeName; + } + + public void setVolumeName(EntityModel<String> volumeName) { + this.volumeName = volumeName; + } + + public EntityModel<String> getSnapshotName() { + return snapshotName; + } + + public void setSnapshotName(EntityModel<String> snapshotName) { + this.snapshotName = snapshotName; + } + + public EntityModel<String> getDescription() { + return description; + } + + public void setDescription(EntityModel<String> description) { + this.description = description; + } + + public ListModel<GlusterVolumeSnapshotScheduleRecurrence> getRecurrence() { + return recurrence; + } + + public void setRecurrence(ListModel<GlusterVolumeSnapshotScheduleRecurrence> recurrence) { + this.recurrence = recurrence; + } + + public ListModel<String> getInterval() { + return interval; + } + + public void setInterval(ListModel<String> interval) { + this.interval = interval; + } + + public ListModel<EndDateOptions> getEndByOptions() { + return endByOptions; + } + + public void setEndByOptions(ListModel<EndDateOptions> endByOptions) { + this.endByOptions = endByOptions; + } + + public EntityModel<Date> getEndDate() { + return endDate; + } + + public void setEndDate(EntityModel<Date> endDate) { + this.endDate = endDate; + } + + public boolean isGeneralTabVisible() { + return generalTabVisible; + } + + public void setGeneralTabVisible(boolean generalTabVisible) { + this.generalTabVisible = generalTabVisible; + } + + public boolean isScheduleTabVisible() { + return scheduleTabVisible; + } + + public void setScheduleTabVisible(boolean scheduleTabVisible) { + this.scheduleTabVisible = scheduleTabVisible; + } + + public ListModel<String> getTimeZones() { + return timeZones; + } + + public void setTimeZones(ListModel<String> timeZones) { + this.timeZones = timeZones; + } + + public EntityModel<Date> getStartAt() { + return this.startAt; + } + + public void setStartAt(EntityModel<Date> value) { + this.startAt = value; + } + + public EntityModel<Date> getExecutionTime() { + return this.executionTime; + } + + public void setExecutionTime(EntityModel<Date> value) { + this.executionTime = value; + } + + public ListModel<List<DayOfWeek>> getDaysOfTheWeek() { + return daysOfWeek; + } + + public void setDaysOfTheWeek(ListModel<List<DayOfWeek>> daysOfTheWeek) { + this.daysOfWeek = daysOfTheWeek; + } + + public ListModel<String> getDaysOfMonth() { + return daysOfMonth; + } + + public void setDaysOfMonth(ListModel<String> daysOfMonth) { + this.daysOfMonth = daysOfMonth; + } + + public boolean validate() { + boolean validWeekDays = true; + boolean validMonthDays = true; + boolean validEndDate = true; + getSnapshotName().validateEntity(new IValidation[] { new NotEmptyValidation(), new LengthValidation(128), + new AsciiNameValidation() }); + + if (getRecurrence().getSelectedItem() == GlusterVolumeSnapshotScheduleRecurrence.WEEKLY + && (getDaysOfTheWeek().getSelectedItem() == null || getDaysOfTheWeek().getSelectedItem().isEmpty())) { + setMessage(ConstantsManager.getInstance().getConstants().noWeekDaysSelectedMessage()); + validWeekDays = false; + } + + if (getRecurrence().getSelectedItem() == GlusterVolumeSnapshotScheduleRecurrence.MONTHLY) { + if (getDaysOfMonth().getSelectedItem() == null || getDaysOfMonth().getSelectedItem().equals("")) {//$NON-NLS-1$ + setMessage(ConstantsManager.getInstance().getConstants().noMonthDaysSelectedMessage()); + validMonthDays = false; + } else if (getDaysOfMonth().getSelectedItem().contains(",L") || getDaysOfMonth().getSelectedItem().contains("L,")) {//$NON-NLS-1$//$NON-NLS-2$ + setMessage(ConstantsManager.getInstance().getConstants().lastDayMonthCanBeSelectedAlone()); + validMonthDays = false; + } + } + + if (getEndByOptions().getSelectedItem() == EndDateOptions.HasEndDate + && getEndDate().getEntity().compareTo(getStartAt().getEntity()) < 0) { + setMessage(ConstantsManager.getInstance().getConstants().endDateBeforeStartDate()); + validEndDate = false; + } + + return getSnapshotName().getIsValid() && getDaysOfTheWeek().getIsValid() && getDaysOfMonth().getIsValid() + && validWeekDays && validMonthDays && validEndDate; + } + + public enum EndDateOptions { + HasEndDate(ConstantsManager.getInstance().getConstants().endDateOptionText()), + NoEndDate(ConstantsManager.getInstance().getConstants().noEndDateOptionText()); + + private String description; + + private EndDateOptions(String description) { + this.description = description; + } + + @Override + public String toString() { + return description; + } + } +} diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java index 1559d07..53a2d97 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java @@ -113,6 +113,8 @@ private UICommand stopVolumeProfilingCommand; private UICommand configureClusterSnapshotOptionsCommand; private UICommand configureVolumeSnapshotOptionsCommand; + private UICommand createSnapshotCommand; + private UICommand editSnapshotScheduleCommand; public UICommand getStartRebalanceCommand() { return startRebalanceCommand; @@ -233,6 +235,22 @@ this.configureVolumeSnapshotOptionsCommand = command; } + public UICommand getCreateSnapshotCommand() { + return this.createSnapshotCommand; + } + + public void setCreateSnapshotCommand(UICommand command) { + this.createSnapshotCommand = command; + } + + public UICommand getEditSnapshotScheduleCommand() { + return this.editSnapshotScheduleCommand; + } + + public void setEditSnapshotScheduleCommand(UICommand command) { + this.editSnapshotScheduleCommand = command; + } + public VolumeListModel() { setTitle(ConstantsManager.getInstance().getConstants().volumesTitle()); setApplicationPlace(WebAdminApplicationPlaces.volumeMainTabPlace); @@ -255,6 +273,8 @@ setOptimizeForVirtStoreCommand(new UICommand("OptimizeForVirtStore", this)); //$NON-NLS-1$ setConfigureClusterSnapshotOptionsCommand(new UICommand("configureClusterSnapshotOptions", this)); //$NON-NLS-1$ setConfigureVolumeSnapshotOptionsCommand(new UICommand("configureVolumeSnapshotOptions", this)); //$NON-NLS-1$ + setCreateSnapshotCommand(new UICommand("createSnapshot", this)); //$NON-NLS-1$ + setEditSnapshotScheduleCommand(new UICommand("editSnapshotSchedule", this)); //$NON-NLS-1$ getRemoveVolumeCommand().setIsExecutionAllowed(false); getStartCommand().setIsExecutionAllowed(false); @@ -483,6 +503,8 @@ boolean allowProfileStatisticsDetails = false; boolean allowConfigureClusterSnapshotOptions = true; boolean allowConfigureVolumeSnapshotOptions = false; + boolean allowCreateSnapshot = false; + boolean allowEditSnapshotSchedule = false; if (getSelectedItems() == null || getSelectedItems().size() == 0) { allowStart = false; @@ -530,6 +552,8 @@ } allowStatusRebalance = getRebalanceStatusAvailability(getSelectedItems()); allowProfileStatisticsDetails = getProfileStatisticsAvailability(list); + allowCreateSnapshot = isCreateSnapshotAvailable(list); + allowEditSnapshotSchedule = isEditSnapshotScheduleAvailable(list); } getStartCommand().setIsExecutionAllowed(allowStart); getStopCommand().setIsExecutionAllowed(allowStop); @@ -540,6 +564,8 @@ getOptimizeForVirtStoreCommand().setIsExecutionAllowed(allowOptimize); getConfigureClusterSnapshotOptionsCommand().setIsExecutionAllowed(allowConfigureClusterSnapshotOptions); getConfigureVolumeSnapshotOptionsCommand().setIsExecutionAllowed(allowConfigureVolumeSnapshotOptions); + getCreateSnapshotCommand().setIsExecutionAllowed(allowCreateSnapshot); + getEditSnapshotScheduleCommand().setIsExecutionAllowed(allowEditSnapshotSchedule); // System tree dependent actions. boolean isAvailable = @@ -550,6 +576,15 @@ getStartVolumeProfilingCommand().setIsExecutionAllowed(allowStartProfiling); getStopVolumeProfilingCommand().setIsExecutionAllowed(allowStopProfiling); getShowVolumeProfileDetailsCommand().setIsExecutionAllowed(allowProfileStatisticsDetails); + } + + private boolean isCreateSnapshotAvailable(List<GlusterVolumeEntity> list) { + return ((list.size() == 1) && (list.get(0).getStatus() == GlusterStatus.UP)); + } + + private boolean isEditSnapshotScheduleAvailable(List<GlusterVolumeEntity> list) { + return ((list.size() == 1) && (list.get(0).getStatus() == GlusterStatus.UP) && list.get(0) + .getSnapshotScheduled()); } private boolean isStopProfileAvailable(List<GlusterVolumeEntity> list) { @@ -676,6 +711,10 @@ confirmConfigureVolumeSnapshotOptions(); } else if (command.getName().equalsIgnoreCase("onConfigureVolumeSnapshotOptions")) {//$NON-NLS-1$ onConfigureVolumeSnapshotOptions(); + } else if (command.equals(getCreateSnapshotCommand())) { + getSnapshotListModel().getCreateSnapshotCommand().execute(); + } else if (command.equals(getEditSnapshotScheduleCommand())) { + getSnapshotListModel().getEditSnapshotScheduleCommand().execute(); } } diff --git a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIConstants.java b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIConstants.java index 4d6b287..20181f2 100644 --- a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIConstants.java +++ b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIConstants.java @@ -2502,6 +2502,18 @@ String geoRepForceHelp(); // Gluster Volume Snapshots + @DefaultStringValue("Create/Schedule Snapshot") + String createScheduleVolumeSnapshotTitle(); + + @DefaultStringValue("Edit Snapshot Schedule") + String editVolumeSnapshotScheduleTitle(); + + @DefaultStringValue("Date") + String endDateOptionText(); + + @DefaultStringValue("No End Date") + String noEndDateOptionText(); + @DefaultStringValue("Volume Snapshot - Cluster Options") String configureClusterSnapshotOptionsTitle(); @@ -2569,5 +2581,20 @@ @DefaultStringValue("Last Day") String lastDay(); + + @DefaultStringValue("No week days selected") + String noWeekDaysSelectedMessage(); + + @DefaultStringValue("No month days selected") + String noMonthDaysSelectedMessage(); + + @DefaultStringValue("Last day of month cannot be selected with other month days") + String lastDayMonthCanBeSelectedAlone(); + + @DefaultStringValue("End by date cannot be before start date") + String endDateBeforeStartDate(); + + @DefaultStringValue("Unable to fetch gluster volume snapshot schedule") + String unableToFetchVolumeSnapshotSchedule(); } diff --git a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIMessages.java b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIMessages.java index 8085d6b..dded460 100644 --- a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIMessages.java +++ b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIMessages.java @@ -2,6 +2,8 @@ import java.util.List; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotScheduleRecurrence; + public interface UIMessages extends com.google.gwt.i18n.client.Messages { @DefaultMessage("One of the parameters isn''t supported (available parameter(s): {0})") @@ -439,4 +441,15 @@ @DefaultMessage("Below snapshots would be removed. Do you want to continue?\n\n {0}") String confirmVolumeSnapshotDeleteMessage(String snapshotNames); + + @DefaultMessage("Incorrect enum") + @AlternateMessage({ + "UNKNOWN", "None", + "INTERVAL", "Minutely", + "HOURLY", "Hourly", + "DAILY", "Daily", + "WEEKLY", "Weekly", + "MONTHLY", "Monthly" + }) + String recurrenceType(@Select GlusterVolumeSnapshotScheduleRecurrence recurrence); } diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java index fd60de5..b94ff9d 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java @@ -3929,6 +3929,57 @@ String geoRepSlaveVolume(); // Volume snapshots + @DefaultStringValue("New") + String newVolumeSnapshot(); + + @DefaultStringValue("Edit Schedule") + String editVolumeSnapshotSchedule(); + + @DefaultStringValue("Schedule") + String scheduleLabel(); + + @DefaultStringValue("Recurrence") + String recurrenceLabel(); + + @DefaultStringValue("Interval (mins)") + String intervalLabel(); + + @DefaultStringValue("End By") + String endByLabel(); + + @DefaultStringValue("End By Date") + String endByDateLabel(); + + @DefaultStringValue("Time Zone") + String timeZoneLabel(); + + @DefaultStringValue("Days Of month") + String daysOfMonthLabel(); + + @DefaultStringValue("Days Of Week") + String daysOfWeekLabel(); + + @DefaultStringValue("Start At") + String startAtLabel(); + + @DefaultStringValue("Execution Time") + String executionTimeLabel(); + + @DefaultStringValue("No End Date") + String noEndDateOption(); + + @DefaultStringValue("Date") + String endDateOption(); + + @DefaultStringValue("Snapshot Name Prefix") + String volumeSnapshotNamePrefixLabel(); + + @DefaultStringValue("Snapshot name would be formed in the format <prefix><timestamp>") + String snapshotNameInfo(); + + @DefaultStringValue("Description") + String volumeSnapshotDescriptionLabel(); + @DefaultStringValue("Name") String volumeSnapshotName(); @@ -3949,6 +4000,9 @@ @DefaultStringValue("Snapshot") String volumeSnapshotMainTabTitle(); + + @DefaultStringValue("Snapshot Scheduled") + String snapshotScheduledLabel(); @DefaultStringValue("Options - Cluster") String configureClusterSnapshotOptions(); @@ -3997,4 +4051,7 @@ @DefaultStringValue("Reset") String resetGeoRepSessionConfig(); + + @DefaultStringValue("Frequent creation of snapshots would overload the cluster") + String criticalSnapshotIntervalNote(); } diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java index d7a626f..ed8d80e 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java @@ -42,8 +42,11 @@ import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.AddBrickPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.BrickAdvancedDetailsPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.DetachGlusterHostsPopupPresenterWidget; +import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterClusterSnapshotConfigureOptionsPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeGeoRepActionConfirmPopUpViewPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeGeoReplicationSessionConfigPopupPresenterWidget; +import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeSnapshotConfigureOptionsPopupPresenterWidget; +import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeSnapshotCreatePopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.RemoveBrickPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.RemoveBrickStatusPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.ReplaceBrickPopupPresenterWidget; @@ -281,7 +284,10 @@ import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.BrickAdvancedDetailsPopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.DetachGlusterHostsPopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GeoRepActionConfirmPopUpView; +import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GlusterClusterSnapshotConfigureOptionsPopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GlusterVolumeGeoReplicationSessionConfigPopupView; +import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GlusterVolumeSnapshotConfigureOptionsPopupView; +import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GlusterVolumeSnapshotCreatePopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.RemoveBrickPopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.RemoveBrickStatusPopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.ReplaceBrickPopupView; @@ -771,6 +777,15 @@ SubTabClusterCpuProfilePresenter.ViewDef.class, SubTabClusterCpuProfileView.class, SubTabClusterCpuProfilePresenter.ProxyDef.class); + bindPresenterWidget(GlusterVolumeSnapshotConfigureOptionsPopupPresenterWidget.class, + GlusterVolumeSnapshotConfigureOptionsPopupPresenterWidget.ViewDef.class, + GlusterVolumeSnapshotConfigureOptionsPopupView.class); + bindPresenterWidget(GlusterClusterSnapshotConfigureOptionsPopupPresenterWidget.class, + GlusterClusterSnapshotConfigureOptionsPopupPresenterWidget.ViewDef.class, + GlusterClusterSnapshotConfigureOptionsPopupView.class); + bindPresenterWidget(GlusterVolumeSnapshotCreatePopupPresenterWidget.class, + GlusterVolumeSnapshotCreatePopupPresenterWidget.ViewDef.class, + GlusterVolumeSnapshotCreatePopupView.class); // Host bindPresenter(HostSubTabPanelPresenter.class, diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java index 85176bc..680eb9a 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java @@ -32,8 +32,11 @@ import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.event.EventPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.AddBrickPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.BrickAdvancedDetailsPopupPresenterWidget; +import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterClusterSnapshotConfigureOptionsPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeGeoRepActionConfirmPopUpViewPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeGeoReplicationSessionConfigPopupPresenterWidget; +import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeSnapshotConfigureOptionsPopupPresenterWidget; +import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeSnapshotCreatePopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.RemoveBrickPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.RemoveBrickStatusPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.ReplaceBrickPopupPresenterWidget; @@ -59,7 +62,9 @@ final Provider<VolumePopupPresenterWidget> popupProvider, final Provider<RemoveConfirmationPopupPresenterWidget> removeConfirmPopupProvider, final Provider<VolumeRebalanceStatusPopupPresenterWidget> rebalanceStatusPopupProvider, - final Provider<VolumeProfileStatisticsPopupPresenterWidget> volumeProfileStatsPopupProvider) { + final Provider<VolumeProfileStatisticsPopupPresenterWidget> volumeProfileStatsPopupProvider, + final Provider<GlusterVolumeSnapshotConfigureOptionsPopupPresenterWidget> volumeSnapshotConfigOptionsPopupProvider, + final Provider<GlusterClusterSnapshotConfigureOptionsPopupPresenterWidget> clusterSnapshotConfigOptionsPopupProvider) { return new MainTabModelProvider<GlusterVolumeEntity, VolumeListModel>(eventBus, defaultConfirmPopupProvider, VolumeListModel.class) { @Override public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(VolumeListModel source, @@ -72,6 +77,12 @@ } else if(lastExecutedCommand == getModel().getShowVolumeProfileDetailsCommand() || lastExecutedCommand.getName().equals("showProfileDetails")) {//$NON-NLS-1$ return volumeProfileStatsPopupProvider.get(); + } + else if (lastExecutedCommand == getModel().getConfigureVolumeSnapshotOptionsCommand()) { + return volumeSnapshotConfigOptionsPopupProvider.get(); + } + else if (lastExecutedCommand == getModel().getConfigureClusterSnapshotOptionsCommand()) { + return clusterSnapshotConfigOptionsPopupProvider.get(); } else { return super.getModelPopup(source, lastExecutedCommand, windowModel); @@ -170,7 +181,8 @@ @Provides @Singleton public SearchableDetailModelProvider<GlusterVolumeSnapshotEntity, VolumeListModel, GlusterVolumeSnapshotListModel> getVolumeSnapshotListProvider(EventBus eventBus, - Provider<DefaultConfirmationPopupPresenterWidget> defaultConfirmPopupProvider) { + Provider<DefaultConfirmationPopupPresenterWidget> defaultConfirmPopupProvider, + final Provider<GlusterVolumeSnapshotCreatePopupPresenterWidget> snapshotPopupProvider) { return new SearchableDetailTabModelProvider<GlusterVolumeSnapshotEntity, VolumeListModel, GlusterVolumeSnapshotListModel>(eventBus, defaultConfirmPopupProvider, VolumeListModel.class, @@ -179,6 +191,11 @@ public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(GlusterVolumeSnapshotListModel source, UICommand lastExecutedCommand, Model windowModel) { + if (lastExecutedCommand == getModel().getCreateSnapshotCommand()) { + return snapshotPopupProvider.get(); + } else if (lastExecutedCommand == getModel().getEditSnapshotScheduleCommand()) { + return snapshotPopupProvider.get(); + } return super.getModelPopup(source, lastExecutedCommand, windowModel); } @@ -273,5 +290,4 @@ @Override protected void configure() { } - } diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/GlusterVolumeSnapshotCreatePopupPresenterWidget.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/GlusterVolumeSnapshotCreatePopupPresenterWidget.java new file mode 100644 index 0000000..5385e55 --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/GlusterVolumeSnapshotCreatePopupPresenterWidget.java @@ -0,0 +1,61 @@ +package org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster; + +import org.ovirt.engine.ui.common.presenter.AbstractModelBoundPopupPresenterWidget; +import org.ovirt.engine.ui.common.presenter.popup.DefaultConfirmationPopupPresenterWidget; +import org.ovirt.engine.ui.uicommonweb.models.ListModel; +import org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotModel; +import org.ovirt.engine.ui.uicompat.Event; +import org.ovirt.engine.ui.uicompat.EventArgs; +import org.ovirt.engine.ui.uicompat.IEventListener; + +import com.google.gwt.event.shared.EventBus; +import com.google.inject.Inject; +import com.google.inject.Provider; + +public class GlusterVolumeSnapshotCreatePopupPresenterWidget extends AbstractModelBoundPopupPresenterWidget<GlusterVolumeSnapshotModel, GlusterVolumeSnapshotCreatePopupPresenterWidget.ViewDef> { + @Inject + public GlusterVolumeSnapshotCreatePopupPresenterWidget(EventBus eventBus, + ViewDef view, + Provider<GlusterVolumeSnapshotCreatePopupPresenterWidget> snapshotPopupProvider, + Provider<DefaultConfirmationPopupPresenterWidget> defaultConfirmPopupPrivder) { + super(eventBus, view); + } + + @Override + public void init(final GlusterVolumeSnapshotModel model) { + super.init(model); + + model.getInterval().getSelectedItemChangedEvent().addListener(new IEventListener() { + @Override + public void eventRaised(Event ev, Object sender, EventArgs args) { + getView().setCriticalIntervalLabelVisibility(model, + Integer.parseInt(((ListModel<String>) sender).getSelectedItem())); + } + }); + + model.getRecurrence().getSelectedItemChangedEvent().addListener(new IEventListener() { + @Override + public void eventRaised(Event ev, Object sender, EventArgs args) { + getView().updateVisibilities(model); + getView().setCriticalIntervalLabelVisibility(model, + Integer.parseInt(model.getInterval().getSelectedItem())); + getView().setMessage(null); + } + }); + + model.getEndByOptions().getSelectedItemChangedEvent().addListener(new IEventListener() { + @Override + public void eventRaised(Event ev, Object sender, EventArgs args) { + getView().setEndDateVisibility(model); + } + }); + } + + public interface ViewDef extends AbstractModelBoundPopupPresenterWidget.ViewDef<GlusterVolumeSnapshotModel> { + public void updateVisibilities(GlusterVolumeSnapshotModel object); + + public void setEndDateVisibility(GlusterVolumeSnapshotModel object); + + public void setCriticalIntervalLabelVisibility(GlusterVolumeSnapshotModel object, int value); + } +} diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.java new file mode 100644 index 0000000..c5b998b --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.java @@ -0,0 +1,274 @@ +package org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster; + +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotScheduleRecurrence; +import org.ovirt.engine.core.compat.DayOfWeek; +import org.ovirt.engine.ui.common.idhandler.ElementIdHandler; +import org.ovirt.engine.ui.common.idhandler.WithElementId; +import org.ovirt.engine.ui.common.view.popup.AbstractModelBoundPopupView; +import org.ovirt.engine.ui.common.widget.dialog.InfoIcon; +import org.ovirt.engine.ui.common.widget.dialog.SimpleDialogPanel; +import org.ovirt.engine.ui.common.widget.dialog.tab.DialogTab; +import org.ovirt.engine.ui.common.widget.editor.EntityModelDateTimeBoxEditor; +import org.ovirt.engine.ui.common.widget.editor.ListModelCheckBoxGroupEditor; +import org.ovirt.engine.ui.common.widget.editor.ListModelDaysOfMonthSelectorEditor; +import org.ovirt.engine.ui.common.widget.editor.ListModelListBoxEditor; +import org.ovirt.engine.ui.common.widget.editor.ListModelRadioGroupEditor; +import org.ovirt.engine.ui.common.widget.editor.generic.StringEntityModelLabelEditor; +import org.ovirt.engine.ui.common.widget.editor.generic.StringEntityModelTextBoxEditor; +import org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotModel; +import org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotModel.EndDateOptions; +import org.ovirt.engine.ui.uicompat.ConstantsManager; +import org.ovirt.engine.ui.webadmin.ApplicationConstants; +import org.ovirt.engine.ui.webadmin.ApplicationResources; +import org.ovirt.engine.ui.webadmin.ApplicationTemplates; +import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeSnapshotCreatePopupPresenterWidget; + +import com.google.gwt.core.shared.GWT; +import com.google.gwt.editor.client.SimpleBeanEditorDriver; +import com.google.gwt.event.shared.EventBus; +import com.google.gwt.resources.client.CssResource; +import com.google.gwt.text.shared.AbstractRenderer; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.Label; +import com.google.inject.Inject; + +public class GlusterVolumeSnapshotCreatePopupView extends + AbstractModelBoundPopupView<GlusterVolumeSnapshotModel> implements + GlusterVolumeSnapshotCreatePopupPresenterWidget.ViewDef { + interface Driver + extends + SimpleBeanEditorDriver<GlusterVolumeSnapshotModel, GlusterVolumeSnapshotCreatePopupView> { + } + + interface ViewUiBinder extends + UiBinder<SimpleDialogPanel, GlusterVolumeSnapshotCreatePopupView> { + ViewUiBinder uiBinder = GWT.create(ViewUiBinder.class); + } + + interface ViewIdHandler extends + ElementIdHandler<GlusterVolumeSnapshotCreatePopupView> { + ViewIdHandler idHandler = GWT.create(ViewIdHandler.class); + } + + @UiField + WidgetStyle style; + + @UiField + DialogTab generalTab; + + @UiField + @Path(value = "clusterName.entity") + @WithElementId + StringEntityModelLabelEditor clusterNameEditor; + + @UiField + @Path(value = "volumeName.entity") + @WithElementId + StringEntityModelLabelEditor volumeNameEditor; + + @UiField + @Path(value = "snapshotName.entity") + @WithElementId + StringEntityModelTextBoxEditor snapshotNameEditor; + + @UiField(provided = true) + InfoIcon snapshotNameInfoIcon; + + @UiField + @Path(value = "description.entity") + @WithElementId + StringEntityModelTextBoxEditor snapshotDescriptionEditor; + + @UiField + DialogTab scheduleTab; + + @UiField(provided = true) + @Path(value = "recurrence.selectedItem") + @WithElementId + ListModelListBoxEditor<GlusterVolumeSnapshotScheduleRecurrence> recurrenceEditor; + + @UiField + @Path(value = "timeZones.selectedItem") + @WithElementId + ListModelListBoxEditor<String> timeZoneEditor; + + @UiField(provided = true) + @Path(value = "daysOfTheWeek.selectedItem") + @WithElementId + ListModelCheckBoxGroupEditor<DayOfWeek> daysOfWeekEditor; + + @UiField + @Path(value = "interval.selectedItem") + @WithElementId + ListModelListBoxEditor<String> intervalEditor; + + @UiField + @Path(value = "endByOptions.selectedItem") + @WithElementId + ListModelRadioGroupEditor<EndDateOptions> endByOptionsEditor; + + @UiField(provided = true) + @Path(value = "endDate.entity") + @WithElementId + EntityModelDateTimeBoxEditor endDate; + + @UiField(provided = true) + @Path(value = "startAt.entity") + @WithElementId + EntityModelDateTimeBoxEditor startAtEditor; + + @UiField(provided = true) + @Path(value = "executionTime.entity") + @WithElementId + EntityModelDateTimeBoxEditor executionTimeEditor; + + @UiField + @Path(value = "daysOfMonth.selectedItem") + @WithElementId + ListModelDaysOfMonthSelectorEditor daysOfMonthEditor; + + @UiField + @Ignore + @WithElementId + Label criticalIntervalLabel; + + @UiField + @Ignore + @WithElementId + Label errorMsgLabel; + + private final ApplicationConstants constants; + + private final Driver driver = GWT.create(Driver.class); + + @Inject + public GlusterVolumeSnapshotCreatePopupView(EventBus eventBus, + ApplicationResources resources, ApplicationConstants constants, + ApplicationTemplates templates) { + super(eventBus, resources); + this.constants = constants; + initEditors(constants, resources, templates); + initWidget(ViewUiBinder.uiBinder.createAndBindUi(this)); + ViewIdHandler.idHandler.generateAndSetIds(this); + localize(); + setVisibilities(); + driver.initialize(this); + daysOfWeekEditor.asCheckBoxGroup().clearAllSelections(); + } + + private void initEditors(ApplicationConstants constants, + ApplicationResources resources, ApplicationTemplates templates) { + snapshotNameInfoIcon = new InfoIcon(templates.italicText(constants.snapshotNameInfo()), resources); + startAtEditor = new EntityModelDateTimeBoxEditor(); + daysOfWeekEditor = new ListModelCheckBoxGroupEditor<DayOfWeek>(new AbstractRenderer<DayOfWeek>() { + @Override + public String render(DayOfWeek object) { + return object.toString().substring(0, 3); + } + }); + endDate = new EntityModelDateTimeBoxEditor(); + executionTimeEditor = new EntityModelDateTimeBoxEditor(); + executionTimeEditor.getContentWidget().setDateRequired(false); + recurrenceEditor = + new ListModelListBoxEditor<GlusterVolumeSnapshotScheduleRecurrence>(new AbstractRenderer<GlusterVolumeSnapshotScheduleRecurrence>() { + @Override + public String render(GlusterVolumeSnapshotScheduleRecurrence object) { + return ConstantsManager.getInstance().getMessages().recurrenceType(object); + } + }); + } + + private void localize() { + generalTab.setLabel(constants.generalLabel()); + + clusterNameEditor.setLabel(constants.volumeClusterLabel()); + volumeNameEditor.setLabel(constants.volumeNameLabel()); + snapshotNameEditor.setLabel(constants.volumeSnapshotNamePrefixLabel()); + snapshotDescriptionEditor.setLabel(constants.volumeSnapshotDescriptionLabel()); + + scheduleTab.setLabel(constants.scheduleLabel()); + + recurrenceEditor.setLabel(constants.recurrenceLabel()); + intervalEditor.setLabel(constants.intervalLabel()); + endByOptionsEditor.setLabel(constants.endByLabel()); + + timeZoneEditor.setLabel(constants.timeZoneLabel()); + daysOfMonthEditor.setLabel(constants.daysOfMonthLabel()); + daysOfWeekEditor.setLabel(constants.daysOfWeekLabel()); + startAtEditor.setLabel(constants.startAtLabel()); + endDate.setLabel(constants.endByDateLabel()); + executionTimeEditor.setLabel(constants.executionTimeLabel()); + + criticalIntervalLabel.setText(constants.criticalSnapshotIntervalNote()); + } + + private void setVisibilities() { + criticalIntervalLabel.setVisible(false); + } + + @Override + public void edit(final GlusterVolumeSnapshotModel object) { + driver.edit(object); + updateVisibilities(object); + updateTabVisibilities(object); + } + + @Override + public void updateVisibilities(GlusterVolumeSnapshotModel object) { + GlusterVolumeSnapshotScheduleRecurrence recurrenceOption = object + .getRecurrence().getSelectedItem(); + + intervalEditor.setVisible(recurrenceOption == GlusterVolumeSnapshotScheduleRecurrence.INTERVAL); + endByOptionsEditor.setVisible(recurrenceOption != GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN); + timeZoneEditor.setVisible(recurrenceOption == GlusterVolumeSnapshotScheduleRecurrence.DAILY + || recurrenceOption == GlusterVolumeSnapshotScheduleRecurrence.WEEKLY + || recurrenceOption == GlusterVolumeSnapshotScheduleRecurrence.MONTHLY); + daysOfWeekEditor.setVisible(recurrenceOption == GlusterVolumeSnapshotScheduleRecurrence.WEEKLY); + daysOfMonthEditor.setVisible(recurrenceOption == GlusterVolumeSnapshotScheduleRecurrence.MONTHLY); + startAtEditor.setVisible(recurrenceOption != GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN); + executionTimeEditor.setVisible(recurrenceOption == GlusterVolumeSnapshotScheduleRecurrence.DAILY + || recurrenceOption == GlusterVolumeSnapshotScheduleRecurrence.WEEKLY + || recurrenceOption == GlusterVolumeSnapshotScheduleRecurrence.MONTHLY); + + setEndDateVisibility(object); + } + + @Override + public void setEndDateVisibility(GlusterVolumeSnapshotModel object) { + endDate.setVisible(object.getRecurrence().getSelectedItem() != GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN + && object.getEndByOptions().getSelectedItem() == EndDateOptions.HasEndDate); + } + + @Override + public void setCriticalIntervalLabelVisibility(GlusterVolumeSnapshotModel object, int interval) { + if (object.getRecurrence().getSelectedItem() == GlusterVolumeSnapshotScheduleRecurrence.INTERVAL) { + criticalIntervalLabel.setVisible(interval <= 30); + } else { + criticalIntervalLabel.setVisible(false); + } + } + + @Override + public void setMessage(String msg) { + super.setMessage(msg); + errorMsgLabel.setText(msg); + } + + private void updateTabVisibilities(GlusterVolumeSnapshotModel object) { + generalTab.setVisible(object.isGeneralTabVisible()); + scheduleTab.setVisible(object.isScheduleTabVisible()); + if (object.getRecurrence().getSelectedItem() != GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN) { + scheduleTab.activate(); + } + } + + @Override + public GlusterVolumeSnapshotModel flush() { + return driver.flush(); + } + + interface WidgetStyle extends CssResource { + String editorContentWidget(); + } +} diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.ui.xml b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.ui.xml new file mode 100644 index 0000000..bd18806 --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.ui.xml @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!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:d="urn:import:org.ovirt.engine.ui.common.widget.dialog" + xmlns:ge="urn:import:org.ovirt.engine.ui.common.widget.editor.generic" + xmlns:e="urn:import:org.ovirt.engine.ui.common.widget.editor" xmlns:w="urn:import:org.ovirt.engine.ui.common.widget" + xmlns:t="urn:import:org.ovirt.engine.ui.common.widget.dialog.tab"> + + <ui:style + type="org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GlusterVolumeSnapshotCreatePopupView.WidgetStyle"> + .panelStyle { + width:470px; + height:500px; + } + + .editorContentWidget{ + width: 50px; + } + + .criticalIntervalLabel { + width: 450px; + height: + 50px; + font-size: 13px; + left: 10px; + padding-left: 15px; + padding-bottom: + 10px; + color: #FF0000; + } + + .errMsgLabel { + width: 450px; + height: 50px; + font-size: 13px; + left: 10px; + color: #FF0000; + } + + .snapshotNameInfoIcon { + width: 15px; + } + + .snapshotName{ + width: 470px; + } + + .daysOfMonthEditor { + padding-bottom: 10px; + } + + .endDate { + padding-bottom: 10px; + } + + </ui:style> + + <d:SimpleDialogPanel width="700px" height="500px"> + <d:content> + <t:DialogTabPanel height="100%" width="100%"> + <t:tab> + <t:DialogTab ui:field="generalTab"> + <t:content> + <g:FlowPanel addStyleNames="{style.panelStyle}"> + <ge:StringEntityModelLabelEditor + ui:field="clusterNameEditor" /> + <ge:StringEntityModelLabelEditor + ui:field="volumeNameEditor" /> + <g:HorizontalPanel> + <ge:StringEntityModelTextBoxEditor + ui:field="snapshotNameEditor" addStyleNames="{style.snapshotName}" /> + <d:InfoIcon ui:field="snapshotNameInfoIcon" + addStyleNames="{style.snapshotNameInfoIcon}" /> + </g:HorizontalPanel> + <ge:StringEntityModelTextBoxEditor + ui:field="snapshotDescriptionEditor" /> + </g:FlowPanel> + </t:content> + </t:DialogTab> + </t:tab> + <t:tab> + <t:DialogTab ui:field="scheduleTab"> + <t:content> + <g:FlowPanel addStyleNames="{style.panelStyle}"> + <e:ListModelListBoxEditor ui:field="recurrenceEditor" /> + <e:ListModelListBoxEditor ui:field="intervalEditor" /> + <e:ListModelListBoxEditor ui:field="timeZoneEditor" /> + <e:EntityModelDateTimeBoxEditor + ui:field="startAtEditor" /> + <e:EntityModelDateTimeBoxEditor + ui:field="executionTimeEditor" /> + <e:ListModelCheckBoxGroupEditor + ui:field="daysOfWeekEditor" /> + <e:ListModelDaysOfMonthSelectorEditor + ui:field="daysOfMonthEditor" addStyleNames="{style.daysOfMonthEditor}" /> + <e:ListModelRadioGroupEditor + ui:field="endByOptionsEditor" /> + <e:EntityModelDateTimeBoxEditor + ui:field="endDate" addStyleNames="{style.endDate}"/> + <g:Label ui:field="criticalIntervalLabel" + addStyleNames="{style.criticalIntervalLabel}" /> + <g:Label ui:field="errorMsgLabel" + addStyleNames="{style.errMsgLabel}" /> + </g:FlowPanel> + </t:content> + </t:DialogTab> + </t:tab> + </t:DialogTabPanel> + </d:content> + </d:SimpleDialogPanel> +</ui:UiBinder> \ No newline at end of file diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java index 7ce2797..96d32e2 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java @@ -165,6 +165,16 @@ snapshotCountColumn.makeSortable(); getTable().addColumn(snapshotCountColumn, constants.noOfSnapshotsLabel(), "100px"); //$NON-NLS-1$ + TextColumnWithTooltip<GlusterVolumeEntity> snapshotScheduledColumn = + new TextColumnWithTooltip<GlusterVolumeEntity>() { + @Override + public String getValue(GlusterVolumeEntity object) { + return object.getSnapshotScheduled().toString(); + } + }; + snapshotScheduledColumn.makeSortable(); + getTable().addColumn(snapshotScheduledColumn, constants.snapshotScheduledLabel(), "100px"); //$NON-NLS-1$ + getTable().addActionButton(new WebAdminButtonDefinition<GlusterVolumeEntity>(constants.newVolume()) { @Override protected UICommand resolveCommand() { @@ -232,7 +242,25 @@ } private List<ActionButtonDefinition<GlusterVolumeEntity>> getVolumeSnapshotMenu(ApplicationConstants constants) { - List<ActionButtonDefinition<GlusterVolumeEntity>> snapshotMenu = new ArrayList<ActionButtonDefinition<GlusterVolumeEntity>>(); + List<ActionButtonDefinition<GlusterVolumeEntity>> snapshotMenu = + new ArrayList<ActionButtonDefinition<GlusterVolumeEntity>>(); + + WebAdminButtonDefinition<GlusterVolumeEntity> newSnapshotButton = + new WebAdminButtonDefinition<GlusterVolumeEntity>(constants.newVolumeSnapshot()) { + @Override + protected UICommand resolveCommand() { + return getMainModel().getCreateSnapshotCommand(); + } + }; + snapshotMenu.add(newSnapshotButton); + WebAdminButtonDefinition<GlusterVolumeEntity> editSnapshotScheduleButton = + new WebAdminButtonDefinition<GlusterVolumeEntity>(constants.editVolumeSnapshotSchedule()) { + @Override + protected UICommand resolveCommand() { + return getMainModel().getEditSnapshotScheduleCommand(); + } + }; + snapshotMenu.add(editSnapshotScheduleButton); WebAdminButtonDefinition<GlusterVolumeEntity> configureClusterSnapshotOptionsButton = new WebAdminButtonDefinition<GlusterVolumeEntity>(constants.configureClusterSnapshotOptions()) { @Override @@ -249,6 +277,7 @@ snapshotMenu.add(configureClusterSnapshotOptionsButton); snapshotMenu.add(configureVolumeSnapshotOptionsButton); + return snapshotMenu; } -- To view, visit https://gerrit.ovirt.org/40004 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I823580ecb127e48e075c437668bfb19ff8ec4467 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: ovirt-engine-3.5-gluster Gerrit-Owner: Shubhendu Tripathi <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
