Add schedule twin update and invoke method UI
Add opendb file to .gitignore Remove miss compiled main.css file Merged files from remote Add opendb file to .ignore , revert temp local change Remove webcomplier realted configs from project Fix merge issue
This commit is contained in:
Родитель
e1d07fa1b8
Коммит
a5fb94c4a6
|
@ -8,6 +8,7 @@
|
|||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
*.opendb
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
|
|
|
@ -529,6 +529,15 @@ namespace GlobalResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Clear.
|
||||
/// </summary>
|
||||
public static string Clear {
|
||||
get {
|
||||
return ResourceManager.GetString("Clear", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to - CLEAR CLAUSE.
|
||||
/// </summary>
|
||||
|
@ -2383,6 +2392,15 @@ namespace GlobalResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to MAXEXECUTION TIME.
|
||||
/// </summary>
|
||||
public static string MaxExecutionTime {
|
||||
get {
|
||||
return ResourceManager.GetString("MaxExecutionTime", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Price cannot be longer than 1024 characters..
|
||||
/// </summary>
|
||||
|
@ -2419,6 +2437,15 @@ namespace GlobalResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Method.
|
||||
/// </summary>
|
||||
public static string Method {
|
||||
get {
|
||||
return ResourceManager.GetString("Method", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Microsoft Azure.
|
||||
/// </summary>
|
||||
|
@ -2896,6 +2923,15 @@ namespace GlobalResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Query.
|
||||
/// </summary>
|
||||
public static string Query {
|
||||
get {
|
||||
return ResourceManager.GetString("Query", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The query name or filters are empty..
|
||||
/// </summary>
|
||||
|
@ -3085,6 +3121,15 @@ namespace GlobalResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This field is required.
|
||||
/// </summary>
|
||||
public static string RequiredValidationString {
|
||||
get {
|
||||
return ResourceManager.GetString("RequiredValidationString", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This field is required.
|
||||
/// </summary>
|
||||
|
@ -3319,6 +3364,51 @@ namespace GlobalResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Change Desired Properties.
|
||||
/// </summary>
|
||||
public static string ScheduleChangeDesiredProperties {
|
||||
get {
|
||||
return ResourceManager.GetString("ScheduleChangeDesiredProperties", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Change Tags.
|
||||
/// </summary>
|
||||
public static string ScheduleChangeTags {
|
||||
get {
|
||||
return ResourceManager.GetString("ScheduleChangeTags", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Desired Property Name.
|
||||
/// </summary>
|
||||
public static string ScheduleDesiredPropertyName {
|
||||
get {
|
||||
return ResourceManager.GetString("ScheduleDesiredPropertyName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Edit Properties or Tags.
|
||||
/// </summary>
|
||||
public static string ScheduleEditPropertiesOrTags {
|
||||
get {
|
||||
return ResourceManager.GetString("ScheduleEditPropertiesOrTags", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Edit Value.
|
||||
/// </summary>
|
||||
public static string ScheduleEditValue {
|
||||
get {
|
||||
return ResourceManager.GetString("ScheduleEditValue", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Schedule Job.
|
||||
/// </summary>
|
||||
|
@ -3337,6 +3427,24 @@ namespace GlobalResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Job Name.
|
||||
/// </summary>
|
||||
public static string ScheduleJobName {
|
||||
get {
|
||||
return ResourceManager.GetString("ScheduleJobName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Enter you job name here.
|
||||
/// </summary>
|
||||
public static string ScheduleJobNamePlaceHolder {
|
||||
get {
|
||||
return ResourceManager.GetString("ScheduleJobNamePlaceHolder", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to SCHEDULE JOB.
|
||||
/// </summary>
|
||||
|
@ -3346,6 +3454,33 @@ namespace GlobalResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Parameters.
|
||||
/// </summary>
|
||||
public static string ScheduleParameterName {
|
||||
get {
|
||||
return ResourceManager.GetString("ScheduleParameterName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Parameters.
|
||||
/// </summary>
|
||||
public static string ScheduleParameters {
|
||||
get {
|
||||
return ResourceManager.GetString("ScheduleParameters", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Set Job Time.
|
||||
/// </summary>
|
||||
public static string ScheduleSetJobTime {
|
||||
get {
|
||||
return ResourceManager.GetString("ScheduleSetJobTime", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to SEARCH DEVICES.
|
||||
/// </summary>
|
||||
|
@ -3634,6 +3769,33 @@ namespace GlobalResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} of {1} devices inapplicable.
|
||||
/// </summary>
|
||||
public static string SomeDeviceInapplicable {
|
||||
get {
|
||||
return ResourceManager.GetString("SomeDeviceInapplicable", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} of {1} devices applicable.
|
||||
/// </summary>
|
||||
public static string SomeDevicesApplicable {
|
||||
get {
|
||||
return ResourceManager.GetString("SomeDevicesApplicable", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to START TIME.
|
||||
/// </summary>
|
||||
public static string StartTime {
|
||||
get {
|
||||
return ResourceManager.GetString("StartTime", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Status.
|
||||
/// </summary>
|
||||
|
@ -3697,6 +3859,15 @@ namespace GlobalResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Tag Name.
|
||||
/// </summary>
|
||||
public static string TagName {
|
||||
get {
|
||||
return ResourceManager.GetString("TagName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Tags.
|
||||
/// </summary>
|
||||
|
|
|
@ -1734,6 +1734,10 @@
|
|||
<value>View all ({0})</value>
|
||||
<comment>Button label.</comment>
|
||||
</data>
|
||||
<data name="Clear" xml:space="preserve">
|
||||
<value>Clear</value>
|
||||
<comment>Hyperlink label</comment>
|
||||
</data>
|
||||
<data name="SelectedColumns" xml:space="preserve">
|
||||
<value>Selected Columns</value>
|
||||
<comment>Section heading.</comment>
|
||||
|
@ -1750,6 +1754,66 @@
|
|||
<value>Delete</value>
|
||||
<comment>Button label.</comment>
|
||||
</data>
|
||||
<data name="MaxExecutionTime" xml:space="preserve">
|
||||
<value>MAXEXECUTION TIME</value>
|
||||
<comment>Input label</comment>
|
||||
</data>
|
||||
<data name="Method" xml:space="preserve">
|
||||
<value>Method</value>
|
||||
<comment>Input label</comment>
|
||||
</data>
|
||||
<data name="Query" xml:space="preserve">
|
||||
<value>Query</value>
|
||||
<comment>Hyperlink label</comment>
|
||||
</data>
|
||||
<data name="ScheduleChangeDesiredProperties" xml:space="preserve">
|
||||
<value>Change Desired Properties</value>
|
||||
<comment>Input label</comment>
|
||||
</data>
|
||||
<data name="ScheduleChangeTags" xml:space="preserve">
|
||||
<value>Change Tags</value>
|
||||
<comment>Input label</comment>
|
||||
</data>
|
||||
<data name="ScheduleDesiredPropertyName" xml:space="preserve">
|
||||
<value>Desired Property Name</value>
|
||||
<comment>Input label</comment>
|
||||
</data>
|
||||
<data name="ScheduleEditPropertiesOrTags" xml:space="preserve">
|
||||
<value>Edit Properties or Tags</value>
|
||||
<comment>Label</comment>
|
||||
</data>
|
||||
<data name="ScheduleEditValue" xml:space="preserve">
|
||||
<value>Edit Value</value>
|
||||
<comment>Input label</comment>
|
||||
</data>
|
||||
<data name="ScheduleJobName" xml:space="preserve">
|
||||
<value>Job Name</value>
|
||||
<comment>Input label</comment>
|
||||
</data>
|
||||
<data name="ScheduleSetJobTime" xml:space="preserve">
|
||||
<value>Set Job Time</value>
|
||||
<comment>Input label</comment>
|
||||
</data>
|
||||
<data name="SomeDeviceInapplicable" xml:space="preserve">
|
||||
<value>{0} of {1} devices inapplicable</value>
|
||||
<comment>label</comment>
|
||||
</data>
|
||||
<data name="SomeDevicesApplicable" xml:space="preserve">
|
||||
<value>{0} of {1} devices applicable</value>
|
||||
<comment>label</comment>
|
||||
</data>
|
||||
<data name="StartTime" xml:space="preserve">
|
||||
<value>START TIME</value>
|
||||
<comment>Input label</comment>
|
||||
</data>
|
||||
<data name="TagName" xml:space="preserve">
|
||||
<value>Tag Name</value>
|
||||
<comment>Input label</comment>
|
||||
</data>
|
||||
<data name="ScheduleJobNamePlaceHolder" xml:space="preserve">
|
||||
<value>Enter you job name here</value>
|
||||
<comment>Placeholder message</comment>
|
||||
</data>
|
||||
<data name="MoveDown" xml:space="preserve">
|
||||
<value>Move down</value>
|
||||
<comment>Button label.</comment>
|
||||
|
@ -1901,4 +1965,15 @@
|
|||
<value>Unable to schedule job. An unexpected error occurred.</value>
|
||||
<comment>Error message.</comment>
|
||||
</data>
|
||||
<data name="RequiredValidationString" xml:space="preserve">
|
||||
<value>This field is required</value>
|
||||
<comment>Error message</comment>
|
||||
</data>
|
||||
<data name="ScheduleParameterName" xml:space="preserve">
|
||||
<value>Parameters</value>
|
||||
</data>
|
||||
<data name="ScheduleParameters" xml:space="preserve">
|
||||
<value>Parameters</value>
|
||||
<comment>Input Label</comment>
|
||||
</data>
|
||||
</root>
|
|
@ -31,6 +31,9 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web
|
|||
bundles.Add(new ScriptBundle("~/bundles/bootstrap")
|
||||
.Include(
|
||||
"~/Scripts/bootstrap.min.js"));
|
||||
bundles.Add(new ScriptBundle("~/bundles/bootstrapdatetime")
|
||||
.Include(
|
||||
"~/Scripts/bootstrap-datetimepicker.min.js"));
|
||||
|
||||
bundles.Add(new ScriptBundle("~/bundles/knockout").Include(
|
||||
"~/Scripts/knockout-{version}.js"));
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.App_Start
|
||||
{
|
||||
public class DateTimeBinder : IModelBinder
|
||||
{
|
||||
public String DateFormat { get; set; }
|
||||
public String TimeFormat { get; set; }
|
||||
|
||||
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
|
||||
{
|
||||
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
|
||||
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
|
||||
|
||||
DateTime result;
|
||||
if (DateTime.TryParseExact(value.AttemptedValue, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None,out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
else if(DateTime.TryParseExact(value.AttemptedValue, TimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
else if(DateTime.TryParse(value.AttemptedValue, out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class NullableDateTimeBinder : IModelBinder
|
||||
{
|
||||
public String DateFormat { get; set; }
|
||||
public String TimeFormat { get; set; }
|
||||
|
||||
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
|
||||
{
|
||||
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
|
||||
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
|
||||
|
||||
DateTime result;
|
||||
if (value !=null && DateTime.TryParseExact(value.AttemptedValue, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
else if (value != null && DateTime.TryParseExact(value.AttemptedValue, TimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
else if (DateTime.TryParse(value.AttemptedValue, out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,352 @@
|
|||
/*!
|
||||
* Datetimepicker for Bootstrap 3
|
||||
* version : 4.17.43
|
||||
* https://github.com/Eonasdan/bootstrap-datetimepicker/
|
||||
*/
|
||||
@bs-datetimepicker-timepicker-font-size: 1.2em;
|
||||
@bs-datetimepicker-active-bg: @btn-primary-bg;
|
||||
@bs-datetimepicker-active-color: @btn-primary-color;
|
||||
@bs-datetimepicker-border-radius: @border-radius-base;
|
||||
@bs-datetimepicker-btn-hover-bg: @gray-lighter;
|
||||
@bs-datetimepicker-disabled-color: @gray-light;
|
||||
@bs-datetimepicker-alternate-color: @gray-light;
|
||||
@bs-datetimepicker-secondary-border-color: #ccc;
|
||||
@bs-datetimepicker-secondary-border-color-rgba: rgba(0, 0, 0, 0.2);
|
||||
@bs-datetimepicker-primary-border-color: white;
|
||||
@bs-datetimepicker-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
|
||||
.bootstrap-datetimepicker-widget {
|
||||
list-style: none;
|
||||
|
||||
&.dropdown-menu {
|
||||
margin: 2px 0;
|
||||
padding: 4px;
|
||||
width: 19em;
|
||||
|
||||
&.timepicker-sbs {
|
||||
@media (min-width: @screen-sm-min) {
|
||||
width: 38em;
|
||||
}
|
||||
|
||||
@media (min-width: @screen-md-min) {
|
||||
width: 38em;
|
||||
}
|
||||
|
||||
@media (min-width: @screen-lg-min) {
|
||||
width: 38em;
|
||||
}
|
||||
}
|
||||
|
||||
&:before, &:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
&.bottom {
|
||||
&:before {
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid @bs-datetimepicker-secondary-border-color;
|
||||
border-bottom-color: @bs-datetimepicker-secondary-border-color-rgba;
|
||||
top: -7px;
|
||||
left: 7px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid @bs-datetimepicker-primary-border-color;
|
||||
top: -6px;
|
||||
left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&.top {
|
||||
&:before {
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-top: 7px solid @bs-datetimepicker-secondary-border-color;
|
||||
border-top-color: @bs-datetimepicker-secondary-border-color-rgba;
|
||||
bottom: -7px;
|
||||
left: 6px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid @bs-datetimepicker-primary-border-color;
|
||||
bottom: -6px;
|
||||
left: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
&.pull-right {
|
||||
&:before {
|
||||
left: auto;
|
||||
right: 6px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
left: auto;
|
||||
right: 7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-unstyled {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a[data-action] {
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
a[data-action]:active {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.timepicker-hour, .timepicker-minute, .timepicker-second {
|
||||
width: 54px;
|
||||
font-weight: bold;
|
||||
font-size: @bs-datetimepicker-timepicker-font-size;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button[data-action] {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.btn[data-action="incrementHours"]::after {
|
||||
.sr-only();
|
||||
content: "Increment Hours";
|
||||
}
|
||||
|
||||
.btn[data-action="incrementMinutes"]::after {
|
||||
.sr-only();
|
||||
content: "Increment Minutes";
|
||||
}
|
||||
|
||||
.btn[data-action="decrementHours"]::after {
|
||||
.sr-only();
|
||||
content: "Decrement Hours";
|
||||
}
|
||||
|
||||
.btn[data-action="decrementMinutes"]::after {
|
||||
.sr-only();
|
||||
content: "Decrement Minutes";
|
||||
}
|
||||
|
||||
.btn[data-action="showHours"]::after {
|
||||
.sr-only();
|
||||
content: "Show Hours";
|
||||
}
|
||||
|
||||
.btn[data-action="showMinutes"]::after {
|
||||
.sr-only();
|
||||
content: "Show Minutes";
|
||||
}
|
||||
|
||||
.btn[data-action="togglePeriod"]::after {
|
||||
.sr-only();
|
||||
content: "Toggle AM/PM";
|
||||
}
|
||||
|
||||
.btn[data-action="clear"]::after {
|
||||
.sr-only();
|
||||
content: "Clear the picker";
|
||||
}
|
||||
|
||||
.btn[data-action="today"]::after {
|
||||
.sr-only();
|
||||
content: "Set the date to today";
|
||||
}
|
||||
|
||||
.picker-switch {
|
||||
text-align: center;
|
||||
|
||||
&::after {
|
||||
.sr-only();
|
||||
content: "Toggle Date and Time Screens";
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: auto;
|
||||
width: auto;
|
||||
line-height: inherit;
|
||||
|
||||
span {
|
||||
line-height: 2.5;
|
||||
height: 2.5em;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
|
||||
|
||||
& td,
|
||||
& th {
|
||||
text-align: center;
|
||||
border-radius: @bs-datetimepicker-border-radius;
|
||||
}
|
||||
|
||||
& th {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
|
||||
&.picker-switch {
|
||||
width: 145px;
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&.disabled:hover {
|
||||
background: none;
|
||||
color: @bs-datetimepicker-disabled-color;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.prev::after {
|
||||
.sr-only();
|
||||
content: "Previous Month";
|
||||
}
|
||||
|
||||
&.next::after {
|
||||
.sr-only();
|
||||
content: "Next Month";
|
||||
}
|
||||
}
|
||||
|
||||
& thead tr:first-child th {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: @bs-datetimepicker-btn-hover-bg;
|
||||
}
|
||||
}
|
||||
|
||||
& td {
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
width: 54px;
|
||||
|
||||
&.cw {
|
||||
font-size: .8em;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
color: @bs-datetimepicker-alternate-color;
|
||||
}
|
||||
|
||||
&.day {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
&.day:hover,
|
||||
&.hour:hover,
|
||||
&.minute:hover,
|
||||
&.second:hover {
|
||||
background: @bs-datetimepicker-btn-hover-bg;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.old,
|
||||
&.new {
|
||||
color: @bs-datetimepicker-alternate-color;
|
||||
}
|
||||
|
||||
&.today {
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border: solid transparent;
|
||||
border-width: 0 0 7px 7px;
|
||||
border-bottom-color: @bs-datetimepicker-active-bg;
|
||||
border-top-color: @bs-datetimepicker-secondary-border-color-rgba;
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&.active,
|
||||
&.active:hover {
|
||||
background-color: @bs-datetimepicker-active-bg;
|
||||
color: @bs-datetimepicker-active-color;
|
||||
text-shadow: @bs-datetimepicker-text-shadow;
|
||||
}
|
||||
|
||||
&.active.today:before {
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&.disabled:hover {
|
||||
background: none;
|
||||
color: @bs-datetimepicker-disabled-color;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
margin: 2px 1.5px;
|
||||
cursor: pointer;
|
||||
border-radius: @bs-datetimepicker-border-radius;
|
||||
|
||||
&:hover {
|
||||
background: @bs-datetimepicker-btn-hover-bg;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: @bs-datetimepicker-active-bg;
|
||||
color: @bs-datetimepicker-active-color;
|
||||
text-shadow: @bs-datetimepicker-text-shadow;
|
||||
}
|
||||
|
||||
&.old {
|
||||
color: @bs-datetimepicker-alternate-color;
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&.disabled:hover {
|
||||
background: none;
|
||||
color: @bs-datetimepicker-disabled-color;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.usetwentyfour {
|
||||
td.hour {
|
||||
height: 27px;
|
||||
line-height: 27px;
|
||||
}
|
||||
}
|
||||
|
||||
&.wider {
|
||||
width: 21em;
|
||||
}
|
||||
|
||||
& .datepicker-decades .decade {
|
||||
line-height: 1.8em !important;
|
||||
}
|
||||
}
|
||||
|
||||
.input-group.date {
|
||||
& .input-group-addon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
|
@ -13,6 +13,27 @@
|
|||
clear: both;
|
||||
}
|
||||
|
||||
.edit_form__labelHeader{
|
||||
color: @form-fieldset-textbox-label;
|
||||
font-size: .6em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.values_editor__group input[type=checkbox]{
|
||||
border: 1px solid @form-textbox-border;
|
||||
background-color: @form-textbox-background;
|
||||
margin: .25em 1em 0em 0;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
.values_editor__group td{
|
||||
text-align:center
|
||||
}
|
||||
|
||||
.values_editor__group>span{
|
||||
font-size:.70em
|
||||
}
|
||||
|
||||
.edit_form__text {
|
||||
display: block;
|
||||
float: left;
|
||||
|
@ -26,6 +47,36 @@
|
|||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.edit_form__texthalf {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 230px;
|
||||
margin: .25em 1em 0 0;
|
||||
border: 1px solid @form-textbox-border;
|
||||
background-color: @form-textbox-background;
|
||||
font-size: .85em;
|
||||
padding: 0 5px;
|
||||
min-height: 30px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.edit_form__textsmall{
|
||||
display: block;
|
||||
float: left;
|
||||
width: 50px;
|
||||
margin: .25em 0em 1.4em 0;
|
||||
border: 1px solid @form-textbox-border;
|
||||
background-color: @form-textbox-background;
|
||||
font-size: .85em;
|
||||
padding: 0 5px;
|
||||
min-height: 30px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
.non_float{
|
||||
float:none;
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.edit_form__text:disabled {
|
||||
color: @form-textbox-disabled-color;
|
||||
background-color: @form-textbox-disabled-background;
|
||||
|
|
17
DeviceAdministration/Web/Content/styles/bootstrap-datetimepicker-build.less
поставляемый
Normal file
17
DeviceAdministration/Web/Content/styles/bootstrap-datetimepicker-build.less
поставляемый
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Import bootstrap variables including default color palette and fonts
|
||||
@import "bootstrap/variables.less";
|
||||
|
||||
// Import datepicker component
|
||||
@import "_bootstrap-datetimepicker.less";
|
||||
|
||||
//this is here so the compiler doesn't complain about a missing bootstrap mixin
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0,0,0,0);
|
||||
border: 0;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
.glyphicon {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
display: inline-block;
|
||||
font-family: 'Tahoma, Geneva, sans-serif';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.glyphicon-calendar {
|
||||
&:before {
|
||||
content: "Date";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.glyphicon-time {
|
||||
&:before {
|
||||
content: "Time";
|
||||
}
|
||||
}
|
|
@ -75,3 +75,7 @@
|
|||
.button_execute {
|
||||
clear: both;
|
||||
}
|
||||
.button_cancel {
|
||||
margin-left : .5em;
|
||||
margin-right : .5em;
|
||||
}
|
|
@ -653,6 +653,24 @@ nav .selected {
|
|||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
.edit_form__labelHeader {
|
||||
color: gray;
|
||||
font-size: 0.6em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.values_editor__group input[type=checkbox] {
|
||||
border: 1px solid #999999;
|
||||
background-color: #f2f2f2;
|
||||
margin: 0.25em 1em 0em 0;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
.values_editor__group td {
|
||||
text-align: center;
|
||||
}
|
||||
.values_editor__group > span {
|
||||
font-size: 0.7em;
|
||||
}
|
||||
.edit_form__text {
|
||||
display: block;
|
||||
float: left;
|
||||
|
@ -665,6 +683,34 @@ nav .selected {
|
|||
min-height: 30px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
.edit_form__texthalf {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 230px;
|
||||
margin: 0.25em 1em 0 0;
|
||||
border: 1px solid #999999;
|
||||
background-color: #f2f2f2;
|
||||
font-size: 0.85em;
|
||||
padding: 0 5px;
|
||||
min-height: 30px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
.edit_form__textsmall {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 50px;
|
||||
margin: 0.25em 0em 1.4em 0;
|
||||
border: 1px solid #999999;
|
||||
background-color: #f2f2f2;
|
||||
font-size: 0.85em;
|
||||
padding: 0 5px;
|
||||
min-height: 30px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
.non_float {
|
||||
float: none;
|
||||
display: inline;
|
||||
}
|
||||
.edit_form__text:disabled {
|
||||
color: #b3b3b3;
|
||||
background-color: #f2f2f2;
|
||||
|
@ -1938,6 +1984,10 @@ table#alertHistoryTable tr.selectedAlert {
|
|||
.button_execute {
|
||||
clear: both;
|
||||
}
|
||||
.button_cancel {
|
||||
margin-left: 0.5em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
.error_noscript {
|
||||
background-color: transparent;
|
||||
color: #ed1c24;
|
||||
|
@ -4277,6 +4327,396 @@ tbody.collapse.in {
|
|||
-webkit-transition-timing-function: ease;
|
||||
transition-timing-function: ease;
|
||||
}
|
||||
/*!
|
||||
* Datetimepicker for Bootstrap 3
|
||||
* version : 4.17.43
|
||||
* https://github.com/Eonasdan/bootstrap-datetimepicker/
|
||||
*/
|
||||
.bootstrap-datetimepicker-widget {
|
||||
list-style: none;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu {
|
||||
margin: 2px 0;
|
||||
padding: 4px;
|
||||
width: 19em;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
|
||||
width: 38em;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
|
||||
width: 38em;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
|
||||
width: 38em;
|
||||
}
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu:before,
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before {
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #cccccc;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
top: -7px;
|
||||
left: 7px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after {
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid white;
|
||||
top: -6px;
|
||||
left: 8px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.top:before {
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-top: 7px solid #cccccc;
|
||||
border-top-color: rgba(0, 0, 0, 0.2);
|
||||
bottom: -7px;
|
||||
left: 6px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.top:after {
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid white;
|
||||
bottom: -6px;
|
||||
left: 7px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before {
|
||||
left: auto;
|
||||
right: 6px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after {
|
||||
left: auto;
|
||||
right: 7px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .list-unstyled {
|
||||
margin: 0;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget a[data-action] {
|
||||
padding: 6px 0;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget a[data-action]:active {
|
||||
box-shadow: none;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .timepicker-hour,
|
||||
.bootstrap-datetimepicker-widget .timepicker-minute,
|
||||
.bootstrap-datetimepicker-widget .timepicker-second {
|
||||
width: 54px;
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
margin: 0;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget button[data-action] {
|
||||
padding: 6px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Increment Hours";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Increment Minutes";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Decrement Hours";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Decrement Minutes";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Show Hours";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Show Minutes";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Toggle AM/PM";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="clear"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Clear the picker";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="today"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Set the date to today";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .picker-switch {
|
||||
text-align: center;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .picker-switch::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Toggle Date and Time Screens";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .picker-switch td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: auto;
|
||||
width: auto;
|
||||
line-height: inherit;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .picker-switch td span {
|
||||
line-height: 2.5;
|
||||
height: 2.5em;
|
||||
width: 100%;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td,
|
||||
.bootstrap-datetimepicker-widget table th {
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table th {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table th.picker-switch {
|
||||
width: 145px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table th.disabled,
|
||||
.bootstrap-datetimepicker-widget table th.disabled:hover {
|
||||
background: none;
|
||||
color: #777777;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table th.prev::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Previous Month";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table th.next::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Next Month";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table thead tr:first-child th {
|
||||
cursor: pointer;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table thead tr:first-child th:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td {
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
width: 54px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.cw {
|
||||
font-size: 0.8em;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
color: #777777;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.day {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.day:hover,
|
||||
.bootstrap-datetimepicker-widget table td.hour:hover,
|
||||
.bootstrap-datetimepicker-widget table td.minute:hover,
|
||||
.bootstrap-datetimepicker-widget table td.second:hover {
|
||||
background: #eeeeee;
|
||||
cursor: pointer;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.old,
|
||||
.bootstrap-datetimepicker-widget table td.new {
|
||||
color: #777777;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.today {
|
||||
position: relative;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.today:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border: solid transparent;
|
||||
border-width: 0 0 7px 7px;
|
||||
border-bottom-color: #337ab7;
|
||||
border-top-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
right: 4px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.active,
|
||||
.bootstrap-datetimepicker-widget table td.active:hover {
|
||||
background-color: #337ab7;
|
||||
color: white;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.active.today:before {
|
||||
border-bottom-color: white;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.disabled,
|
||||
.bootstrap-datetimepicker-widget table td.disabled:hover {
|
||||
background: none;
|
||||
color: #777777;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td span {
|
||||
display: inline-block;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
margin: 2px 1.5px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td span:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td span.active {
|
||||
background-color: #337ab7;
|
||||
color: white;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td span.old {
|
||||
color: #777777;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td span.disabled,
|
||||
.bootstrap-datetimepicker-widget table td span.disabled:hover {
|
||||
background: none;
|
||||
color: #777777;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.usetwentyfour td.hour {
|
||||
height: 27px;
|
||||
line-height: 27px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.wider {
|
||||
width: 21em;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .datepicker-decades .decade {
|
||||
line-height: 1.8em !important;
|
||||
}
|
||||
.input-group.date .input-group-addon {
|
||||
cursor: pointer;
|
||||
}
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
}
|
||||
.glyphicon {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
display: inline-block;
|
||||
font-family: 'Tahoma, Geneva, sans-serif';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
.glyphicon-calendar:before {
|
||||
content: "Date";
|
||||
}
|
||||
.glyphicon-time:before {
|
||||
content: "Time";
|
||||
}
|
||||
.navbar {
|
||||
border-radius: 0px;
|
||||
margin-bottom: 0px;
|
||||
|
|
|
@ -51,6 +51,8 @@ error and can be *very* helpful.
|
|||
|
||||
|
||||
@import "bootstrap/bootstrap.less";
|
||||
@import "bootstrap-datetimepicker-build.less";
|
||||
@import "bootstrap/glyphicon.less";
|
||||
@import "navbars.less";
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ using System.Web.Mvc;
|
|||
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Infrastructure.Repository;
|
||||
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.Models;
|
||||
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.Security;
|
||||
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.Models;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.Controllers
|
||||
{
|
||||
|
@ -52,19 +54,37 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.
|
|||
}
|
||||
|
||||
[RequirePermission(Permission.ManageJobs)]
|
||||
public async Task<ActionResult> ScheduleTwinUpdate()
|
||||
public ActionResult ScheduleTwinUpdate()
|
||||
{
|
||||
//ToDo: Jump to the view with desired model
|
||||
|
||||
return View();
|
||||
return View(new ScheduleTwinUpdateModel());
|
||||
}
|
||||
|
||||
[RequirePermission(Permission.ManageJobs)]
|
||||
public async Task<ActionResult> ScheduleDeviceMethod()
|
||||
[HttpPost]
|
||||
public ActionResult ScheduleTwinUpdate(ScheduleTwinUpdateModel model)
|
||||
{
|
||||
//ToDo: Jump to the view with desired model
|
||||
|
||||
return View();
|
||||
return View(new ScheduleTwinUpdateModel());
|
||||
}
|
||||
|
||||
[RequirePermission(Permission.ManageJobs)]
|
||||
public ActionResult ScheduleDeviceMethod()
|
||||
{
|
||||
//ToDo: Jump to the view with desired model
|
||||
|
||||
return View(new ScheduleDeviceMethodModel());
|
||||
}
|
||||
|
||||
[RequirePermission(Permission.ManageJobs)]
|
||||
[HttpPost]
|
||||
public ActionResult ScheduleDeviceMethod(ScheduleDeviceMethodModel model)
|
||||
{
|
||||
//ToDo: Jump to the view with desired model
|
||||
|
||||
return View(new ScheduleDeviceMethodModel());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ using System.Web.Routing;
|
|||
|
||||
namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web
|
||||
{
|
||||
using App_Start;
|
||||
using Helpers;
|
||||
|
||||
public class MvcApplication : System.Web.HttpApplication
|
||||
|
@ -27,6 +28,8 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web
|
|||
|
||||
// Reset JobList and QueryList via actual current job history for debugging
|
||||
//RepositoryInitializer.SeedTablesAsync().Wait();
|
||||
ModelBinders.Binders.Add(typeof(DateTime), new DateTimeBinder() { TimeFormat = "h:m:ss tt", DateFormat= "MMMM d, yyyy h:mm tt" });
|
||||
ModelBinders.Binders.Add(typeof(DateTime?), new NullableDateTimeBinder() { TimeFormat = "h:m:ss tt", DateFormat = "MMMM d, yyyy h:mm tt" });
|
||||
}
|
||||
|
||||
// Require HTTPS for all requests processed by ASP.NET
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.Models
|
||||
{
|
||||
|
||||
public class MethodParameterEditViewModel
|
||||
{
|
||||
public string ParameterName { get; set; }
|
||||
public string ParameterValue { get; set; }
|
||||
public string ParameterType { get; set; }
|
||||
}
|
||||
|
||||
public class ScheduleDeviceMethodModel : ScheduleJobViewModel
|
||||
{
|
||||
public string MethodName { get; set; }
|
||||
public List<MethodParameterEditViewModel> Parameters { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,7 +1,26 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.Models
|
||||
{
|
||||
public class ScheduleJobViewModel
|
||||
{
|
||||
|
||||
public string QueryName { get; set; }
|
||||
|
||||
[Required]
|
||||
public string JobName { get; set; }
|
||||
|
||||
[Required]
|
||||
public DateTime StartDateUtc { get; set; }
|
||||
|
||||
[Required]
|
||||
public int MaxExecutionTimeInMinutes { get; set; }
|
||||
}
|
||||
|
||||
public class ScheduleJobModel
|
||||
{
|
||||
public string QueryName { get; set; }
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
using GlobalResources;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.Models
|
||||
{
|
||||
public class DesiredPropetiesEditViewModel
|
||||
{
|
||||
public string PropertyName { get; set; }
|
||||
public string PropertyValue { get; set; }
|
||||
public string Valuetype { get; set; }
|
||||
public bool isDeleted { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class TagsEditViewModel
|
||||
{
|
||||
public string TagName { get; set; }
|
||||
public string TagValue { get; set; }
|
||||
public string Valuetype { get; set; }
|
||||
public bool isDeleted { get; set; }
|
||||
}
|
||||
|
||||
public class ScheduleTwinUpdateModel: ScheduleJobViewModel
|
||||
{
|
||||
public List<DesiredPropetiesEditViewModel> DesiredProperties { get; set; }
|
||||
|
||||
public List<TagsEditViewModel> Tags { get; set; }
|
||||
}
|
||||
}
|
|
@ -34,4 +34,44 @@
|
|||
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ko.bindingHandlers.dateTimePicker = {
|
||||
init: function (element, valueAccessor, allBindingsAccessor) {
|
||||
//initialize datepicker with some optional options
|
||||
var options = allBindingsAccessor().dateTimePickerOptions || { };
|
||||
$(element).datetimepicker(options);
|
||||
|
||||
//when a user changes the date, update the view model
|
||||
ko.utils.registerEventHandler(element, "dp.change", function (event) {
|
||||
var value = valueAccessor();
|
||||
if (ko.isObservable(value)) {
|
||||
if (event.date != null && !(event.date instanceof Date)) {
|
||||
value(event.date.toDate());
|
||||
} else {
|
||||
value(event.date);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
|
||||
var picker = $(element).data("DateTimePicker");
|
||||
if (picker) {
|
||||
picker.destroy();
|
||||
}
|
||||
});
|
||||
},
|
||||
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
|
||||
|
||||
var picker = $(element).data("DateTimePicker");
|
||||
//when the view model is updated, update the widget
|
||||
if (picker) {
|
||||
var koDate = ko.utils.unwrapObservable(valueAccessor());
|
||||
|
||||
//in case return from server datetime i am get in this form for example /Date(93989393)/ then fomat this
|
||||
koDate = (typeof (koDate) !== 'object') ? new Date(parseFloat(koDate.replace(/[^0-9]/g, ''))) : koDate;
|
||||
|
||||
picker.date(koDate);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1,69 @@
|
|||
IoTApp.createModule('IoTApp.ScheduleDeviceMethod', function () {
|
||||
'use strict';
|
||||
|
||||
var self = this;
|
||||
|
||||
function MethodParameterEditItem(name, type, value) {
|
||||
var self = this;
|
||||
self.ParameterName = name;
|
||||
self.Type = type
|
||||
self.ParameterValue = value;
|
||||
}
|
||||
|
||||
|
||||
function viewModel() {
|
||||
var self = this;
|
||||
this.queryName = ko.observable("");
|
||||
this.jobName = ko.observable("");
|
||||
this.methodName = ko.observable("");
|
||||
this.methods = {};
|
||||
this.parameters = ko.pureComputed(function () {
|
||||
if (self.methodName != undefined
|
||||
&& self.methodName().length != 0) {
|
||||
|
||||
var rawparam = $.grep(self.methods, function (e) { return e.name == self.methodName(); });
|
||||
if (rawparam.length != 0) {
|
||||
var params = $.map(rawparam[0].parameters, function (item) {
|
||||
return new MethodParameterEditItem(item.name, item.type, "")
|
||||
})
|
||||
return params.length == 0 ? null : params;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}, this);
|
||||
|
||||
this.startDate = ko.observable(moment());
|
||||
this.isParameterLoading = true;
|
||||
this.maxExecutionTime = ko.observable(30);
|
||||
|
||||
this.getMatchedDevices = function (stringtemplate) {
|
||||
return stringtemplate.replace("{0}", "2").replace("{1}", "5");
|
||||
}
|
||||
this.getUnmatchedDevices = function (stringtemplate) {
|
||||
return stringtemplate.replace("{0}", "3").replace("{1}", "5");
|
||||
}
|
||||
|
||||
this.beforePost = function (elem) {
|
||||
$(elem).find("#StartDate").val(moment(this.startDate()).utc().format());
|
||||
return true;
|
||||
}
|
||||
|
||||
this.cacheNameList = function (namelist) {
|
||||
self.methods = namelist;
|
||||
IoTApp.Controls.NameSelector.create(jQuery('.name_selector__text'), { type: IoTApp.Controls.NameSelector.NameListType.method }, self.methods);
|
||||
}
|
||||
|
||||
this.init = function () {
|
||||
IoTApp.Controls.NameSelector.loadNameList({ type: IoTApp.Controls.NameSelector.NameListType.method }, self.cacheNameList)
|
||||
}
|
||||
}
|
||||
|
||||
var vm = new viewModel();
|
||||
return {
|
||||
init: function () {
|
||||
vm.init();
|
||||
ko.applyBindings(vm, $("content").get(0));
|
||||
}
|
||||
}
|
||||
|
||||
}, [jQuery, resources]);
|
|
@ -0,0 +1,117 @@
|
|||
|
||||
|
||||
IoTApp.createModule('IoTApp.ScheduleTwinUpdate', function () {
|
||||
'use strict';
|
||||
|
||||
var self = this;
|
||||
function PropertiesEditItem(name, value, isDeleted) {
|
||||
var self = this;
|
||||
self.PropertyName = name;
|
||||
self.PropertyValue = value;
|
||||
self.isDeleted = isDeleted;
|
||||
}
|
||||
|
||||
function TagsEditItem(name, value, isDeleted) {
|
||||
var self = this;
|
||||
self.TagName = name;
|
||||
self.TagValue = value;
|
||||
self.isDeleted = isDeleted;
|
||||
}
|
||||
|
||||
function viewModel() {
|
||||
var self = this;
|
||||
this.queryName = ko.observable("");
|
||||
this.jobName = ko.observable("");
|
||||
this.properties = ko.observableArray();
|
||||
this.tags = ko.observableArray();
|
||||
this.startDate = ko.observable(moment());
|
||||
this.isPropertiesLoading = true;
|
||||
this.isTagsLoading = true;
|
||||
this.maxExecutionTime = ko.observable(30);
|
||||
this.cachetagList = {};
|
||||
this.cachepropertyList = {};
|
||||
this.onepropleft = ko.observable(true);
|
||||
this.onetagleft = ko.observable(true);
|
||||
this.propertieslist = {};
|
||||
this.tagslist = {};
|
||||
|
||||
this.createEmptyPropertyIfNeeded = function (property) {
|
||||
if (self.properties.indexOf(property) == self.properties().length - 1) {
|
||||
self.properties.push(new PropertiesEditItem("", "", false, false))
|
||||
self.onepropleft(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.createEmptyTagIfNeeded = function (tag) {
|
||||
if (self.tags.indexOf(tag) == self.tags().length - 1) {
|
||||
self.tags.push(new TagsEditItem("", "", false, false))
|
||||
self.onetagleft(false);
|
||||
}
|
||||
}
|
||||
|
||||
this.removeTag = function (tag) {
|
||||
self.tags.remove(tag);
|
||||
if (self.tags().length <=1) {
|
||||
self.onetagleft(true);
|
||||
}
|
||||
}
|
||||
|
||||
this.removeProperty = function (prop) {
|
||||
self.properties.remove(prop);
|
||||
if (self.properties().length <= 1) {
|
||||
self.onepropleft(true);
|
||||
}
|
||||
}
|
||||
|
||||
this.beforePost = function (elem) {
|
||||
$(elem).find("#StartDate").val(moment(this.startDate()).utc().format());
|
||||
return true;
|
||||
}
|
||||
|
||||
this.maketaglist = function (elem, index, data) {
|
||||
self.refreshnamecontrol();
|
||||
}
|
||||
|
||||
this.makeproplist = function (elem, index, data) {
|
||||
self.refreshnamecontrol();
|
||||
}
|
||||
|
||||
this.cachepropertyList = function (namelist) {
|
||||
self.propertieslist = namelist;
|
||||
self.refreshnamecontrol();
|
||||
}
|
||||
|
||||
this.cachetagList = function (namelist) {
|
||||
self.tagslist = namelist;
|
||||
self.refreshnamecontrol();
|
||||
}
|
||||
|
||||
this.refreshnamecontrol = function () {
|
||||
jQuery('.edit_form__texthalf.edit_form__propertiesComboBox').each(function () {
|
||||
IoTApp.Controls.NameSelector.create(jQuery(this), { type: IoTApp.Controls.NameSelector.NameListType.properties }, self.propertieslist);
|
||||
});
|
||||
jQuery('.edit_form__texthalf.edit_form__tagsComboBox').each(function () {
|
||||
IoTApp.Controls.NameSelector.create(jQuery(this), { type: IoTApp.Controls.NameSelector.NameListType.tags }, self.tagslist);
|
||||
});
|
||||
}
|
||||
|
||||
this.init = function () {
|
||||
this.properties.push(new PropertiesEditItem("", "", false));
|
||||
this.tags.push(new TagsEditItem("", "", false));
|
||||
//IoTApp.Controls.NameSelector.loadNameList({ type: IoTApp.Controls.NameSelector.NameListType.tag }, self.cachetagList);
|
||||
//IoTApp.Controls.NameSelector.loadNameList({ type: IoTApp.Controls.NameSelector.NameListType.desiredProperty }, self.cachepropertyList);
|
||||
IoTApp.Controls.NameSelector.loadNameList({ type: IoTApp.Controls.NameSelector.NameListType.method }, self.cachetagList);
|
||||
IoTApp.Controls.NameSelector.loadNameList({ type: IoTApp.Controls.NameSelector.NameListType.method }, self.cachepropertyList);
|
||||
}
|
||||
}
|
||||
|
||||
var vm = new viewModel();
|
||||
return {
|
||||
init: function () {
|
||||
vm.init();
|
||||
ko.applyBindings(vm, $("content").get(0));
|
||||
}
|
||||
}
|
||||
|
||||
}, [jQuery, resources]);
|
|
@ -1,5 +1,6 @@
|
|||
/// <autosync enabled="true" />
|
||||
/// <reference path="bootstrap.min.js" />
|
||||
/// <reference path="bootstrap-datetimepicker.min.js" />
|
||||
/// <reference path="controls.js" />
|
||||
/// <reference path="dialog.js" />
|
||||
/// <reference path="IoTHelperScripts.js" />
|
||||
|
@ -43,3 +44,5 @@
|
|||
/// <reference path="views/devicerules/editdeviceruleproperties.js" />
|
||||
/// <reference path="views/devicerules/removedevicerule.js" />
|
||||
/// <reference path="views/iotapp.js" />
|
||||
/// <reference path="views/job/scheduledevicemethod.js" />
|
||||
/// <reference path="Views/Job/ScheduleTwinUpdate.js" />
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -39,8 +39,8 @@
|
|||
|
||||
$element.autocomplete({
|
||||
source: items,
|
||||
select: function (event, ui) {
|
||||
$element.change();
|
||||
select: function(event,ui){
|
||||
$(this).val(ui.item.value).change();
|
||||
},
|
||||
minLength: 0
|
||||
}).focus(function () {
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
@using System.Globalization
|
||||
@using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Common.Helpers
|
||||
@using Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Infrastructure.Models
|
||||
@using Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.Helpers
|
||||
@using GlobalResources
|
||||
@model Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.Models.ScheduleDeviceMethodModel
|
||||
|
||||
@{
|
||||
ViewBag.Title = @Strings.InvokeMethod;
|
||||
Layout = "~/Views/Shared/_LayoutNoNavigation.cshtml";
|
||||
}
|
||||
|
||||
<header class="header_main">
|
||||
|
||||
<button class="header_main__button_back" type="button"></button>
|
||||
<h2 class="header_main__subhead header_main__subhead--large">@Strings.InvokeMethod <span class="item__description">@Model.QueryName</span></h2>
|
||||
</header>
|
||||
<div class="content_outer">
|
||||
|
||||
<div class="content_inner">
|
||||
<div id="content">
|
||||
<div id="scheduleJobParameter">
|
||||
@using (Html.BeginForm("ScheduleDeviceMethod", "Job", FormMethod.Post , new { data_bind= "submit: beforePost" }))
|
||||
{
|
||||
@Html.AntiForgeryToken()
|
||||
<p>
|
||||
@Html.ValidationSummary(false)
|
||||
</p>
|
||||
|
||||
<fieldset class="edit_form">
|
||||
@{
|
||||
@Html.LabelFor(m => m.JobName, Strings.ScheduleJobName, new { @class = "edit_form__label" });
|
||||
@Html.TextBoxFor(m => m.JobName, new { placeholder = Strings.ScheduleJobNamePlaceHolder, data_bind = "value: jobName", @class = "edit_form__text" });
|
||||
|
||||
<div style="clear:both"></div>
|
||||
@Html.LabelFor(m => m.MethodName, Strings.InvokeMethodLabel, new { @class = "edit_form__label" });
|
||||
@Html.TextBoxFor(m => m.MethodName, new { data_bind = "textInput: methodName, event{ blur: $root.updateParameter }", @class = "name_selector__text edit_form__text" });
|
||||
|
||||
<div style="clear:both"></div>
|
||||
|
||||
<div>
|
||||
<span class="text_small" data-bind="text: getMatchedDevices('@Strings.SomeDevicesApplicable')"></span><a href="/Device/Query">query</a>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text_small" data-bind="text: getUnmatchedDevices('@Strings.SomeDevicesApplicable')"></span><a href="/Device/Query">query</a>
|
||||
</div>
|
||||
|
||||
<div style="clear:both"></div>
|
||||
<label for="parameterTable" class="edit_form__label" data-bind="if: parameters">@Strings.ScheduleParameters</label>
|
||||
<table class="values_editor" id="paramterTable" data-bind="if: parameters">
|
||||
<thead>
|
||||
<tr class="values_editor__groupheader">
|
||||
<th class="edit_form__labelHeader">@Strings.ScheduleParameterName</th>
|
||||
<th class="edit_form__labelHeader">@Strings.ScheduleEditValue</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-bind="foreach:{data: parameters}">
|
||||
<tr class="values_editor__group">
|
||||
<td>
|
||||
<input type="text" class="edit_form__texthalf"
|
||||
data-bind="value: ParameterName, attr: { name: 'Parameters[' + $index()+'].ParameterName', id: 'Parameters' + $index()+'.ParameterName' }" />
|
||||
</td>
|
||||
<td>
|
||||
@*data-msg-required="@Strings.RequiredValidationString"
|
||||
data-rule-required="true"*@
|
||||
<input type="text" class="edit_form__texthalf"
|
||||
data-bind="value: ParameterValue, attr: { name: 'Parameters[' + $index()+'].ParameterValue', id: 'Parameters' + $index()+'.ParameterValue' }" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<label for="scheduleJobTime" class="edit_form__label" >@Strings.ScheduleSetJobTime</label>
|
||||
|
||||
<div id="scheduleJobTime" class="values_editor">
|
||||
<div class="values_editor__group">
|
||||
<label class="edit_form__labelHeader">@Strings.StartTime</label>
|
||||
<input type='text' id="StartDate" name="StartDateUtc" class="edit_form__text non_float" data-bind="dateTimePicker: startDate ,dateTimePickerOptions:{ format: 'LLL' , locale: window.navigator.language}"
|
||||
data-msg-required="@Strings.RequiredValidationString"
|
||||
data-rule-required="true" />
|
||||
</div>
|
||||
<div class="values_editor__group">
|
||||
<label class="edit_form__labelHeader">@Strings.MaxExecutionTime</label>
|
||||
<input type="text" class="edit_form__textsmall non_float" name="MaxExecutionTimeInMinutes" data-bind="value: maxExecutionTime"
|
||||
data-msg-required="@Strings.RequiredValidationString"
|
||||
data-rule-required="true" />
|
||||
<span>Mins</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="fieldset_button">
|
||||
<button class="button_base button_secondary button_cancel">@Strings.Cancel</button>
|
||||
<button class="button_base" type="submit">@Strings.Create</button>
|
||||
</fieldset>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
var resources = {
|
||||
redirectUrl: '@Url.Action("Index", "Device")',
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript" src="~/Scripts/Views/Job/ScheduleDeviceMethod.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
IoTApp.ScheduleDeviceMethod.init();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
@using System.Globalization
|
||||
@using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Common.Helpers
|
||||
@using Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Infrastructure.Models
|
||||
@using Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.Helpers
|
||||
@using GlobalResources
|
||||
@model Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.Models.ScheduleTwinUpdateModel
|
||||
|
||||
@{
|
||||
ViewBag.Title = @Strings.UpdateTwin;
|
||||
Layout = "~/Views/Shared/_LayoutNoNavigation.cshtml";
|
||||
}
|
||||
|
||||
<header class="header_main">
|
||||
|
||||
<button class="header_main__button_back" type="button"></button>
|
||||
<h2 class="header_main__subhead header_main__subhead--large">@Strings.ScheduleEditPropertiesOrTags <span class="item__description">@Model.QueryName</span></h2>
|
||||
</header>
|
||||
<div class="content_outer">
|
||||
|
||||
<div class="content_inner">
|
||||
<div id="content">
|
||||
<div id="scheduleJobParameter">
|
||||
@using (Html.BeginForm("ScheduleTwinUpdate", "Job", FormMethod.Post,new { data_bind="submit: beforePost" }))
|
||||
{
|
||||
@Html.AntiForgeryToken()
|
||||
<p>
|
||||
@Html.ValidationSummary(false)
|
||||
</p>
|
||||
|
||||
<fieldset class="edit_form">
|
||||
@{
|
||||
@Html.LabelFor(m => m.JobName, Strings.ScheduleJobName, new { @class = "edit_form__label" });
|
||||
@Html.TextBoxFor(m => m.JobName, new { placeholder = Strings.ScheduleJobNamePlaceHolder, data_bind = "value: jobName", @class = "edit_form__text" });
|
||||
|
||||
<div style="clear:both"></div>
|
||||
<label for="propertiesTable" class="edit_form__label">@Strings.ScheduleChangeDesiredProperties</label>
|
||||
<table class="values_editor" id="propertiesTable">
|
||||
<thead>
|
||||
<tr class="values_editor__groupheader">
|
||||
<th class="edit_form__labelHeader">@Strings.ScheduleDesiredPropertyName</th>
|
||||
<th class="edit_form__labelHeader">@Strings.ScheduleEditValue</th>
|
||||
<th class="edit_form__labelHeader">@Strings.Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-bind="foreach:{data: properties, afterAdd:makeproplist}">
|
||||
<tr class="values_editor__group">
|
||||
<td>
|
||||
<input type="text" class="edit_form__texthalf edit_form__propertiesComboBox"
|
||||
data-bind="value: PropertyName, attr: { name: 'DesiredProperties[' + $index()+'].PropertyName', id: 'DesiredProperties' + $index()+'.PropertyName' }" />
|
||||
</td>
|
||||
<td>
|
||||
@*data-msg-required="@Strings.RequiredValidationString"
|
||||
data-rule-required="true"*@
|
||||
<input type="text" class="edit_form__texthalf"
|
||||
data-bind="value: PropertyValue, event: { blur: $root.createEmptyPropertyIfNeeded }, attr: { name: 'DesiredProperties[' + $index()+'].PropertyValue', id: 'DesiredProperties' + $index()+'.PropertyValue' }" />
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox"
|
||||
value="true"
|
||||
data-bind="check: isDeleted, attr: { name: 'DesiredProperties[' + $index()+'].isDeleted', id: 'DesiredProperties' + $index()+'.isDeleted' }" />
|
||||
<input type="hidden" value="false" name="checkbox" data-bind="attr:{ name:'DesiredProperties[' + $index()+'].isDeleted'}" />
|
||||
</td>
|
||||
<td><a data-bind="ifnot:$root.onepropleft , click:$root.removeProperty">@Strings.Clear</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<label for="tagsTable" class="edit_form__label">@Strings.ScheduleChangeTags</label>
|
||||
<table class="values_editor" id="tagsTable">
|
||||
<thead>
|
||||
<tr class="values_editor__groupheader">
|
||||
<th class="edit_form__labelHeader">@Strings.TagName</th>
|
||||
<th class="edit_form__labelHeader">@Strings.ScheduleEditValue</th>
|
||||
<th class="edit_form__labelHeader">@Strings.Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-bind="foreach: {data: tags, afterAdd: maketaglist}">
|
||||
<tr class="values_editor__group">
|
||||
|
||||
<td>
|
||||
<input type="text" class="edit_form__texthalf edit_form__tagsComboBox"
|
||||
data-bind="value: TagName, attr: { name: 'Tags[' + $index()+'].TagName', id: 'Tags' + $index()+'.TagName' }" />
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="edit_form__texthalf"
|
||||
data-bind="value: TagValue, event: { blur: $root.createEmptyTagIfNeeded },attr: { name: 'Tags[' + $index()+'].TagValue', id: 'Tags' + $index()+'.TagValue' }" />
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox"
|
||||
value="true"
|
||||
data-bind="check: isDeleted, attr: { name: 'Tags[' + $index()+'].isDeleted', id: 'Tags' + $index()+'.isDeleted' }" />
|
||||
<input type="hidden" value="false" name="checkbox" data-bind="attr:{ name:'Tags[' + $index()+'].isDeleted'}" />
|
||||
</td>
|
||||
<td><a data-bind="ifnot:$root.onetagleft , click:$root.removeTag">@Strings.Clear</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<label for="scheduleJobTime" class="edit_form__label">@Strings.ScheduleSetJobTime</label>
|
||||
|
||||
<div id="scheduleJobTime" class="values_editor">
|
||||
<div class="values_editor__group">
|
||||
<label class="edit_form__labelHeader">@Strings.StartTime</label>
|
||||
<input type='text' id="StartDate" name="StartDateUtc" class="edit_form__text non_float" data-bind="dateTimePicker: startDate ,dateTimePickerOptions:{ format: 'LLL', locale: window.navigator.language}"
|
||||
data-msg-required="@Strings.RequiredValidationString"
|
||||
data-rule-required="true" />
|
||||
</div>
|
||||
<div class="values_editor__group">
|
||||
<label class="edit_form__labelHeader">@Strings.MaxExecutionTime</label>
|
||||
<input type="text" class="edit_form__textsmall non_float" name="MaxExecutionTimeInMinutes" data-bind="value: maxExecutionTime"
|
||||
data-msg-required="@Strings.RequiredValidationString"
|
||||
data-rule-required="true" />
|
||||
<span>Mins</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="fieldset_button">
|
||||
<button class="button_base button_secondary button_cancel">@Strings.Cancel</button>
|
||||
<button class="button_base" type="submit">@Strings.Create</button>
|
||||
</fieldset>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
var resources = {
|
||||
redirectUrl: '@Url.Action("Index", "Device")',
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript" src="~/Scripts/Views/Job/ScheduleTwinUpdate.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
IoTApp.ScheduleTwinUpdate.init();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
@ -25,9 +25,11 @@
|
|||
@Scripts.Render("~/bundles/jquerytable")
|
||||
@Scripts.Render("~/bundles/jqueryui")
|
||||
@Scripts.Render("~/bundles/knockout")
|
||||
@Scripts.Render("~/bundles/bootstrap")
|
||||
<script src="~/Scripts/moment-with-locales.min.js"></script>
|
||||
@Scripts.Render("~/bundles/bootstrapdatetime")
|
||||
|
||||
<script type="text/javascript" src="~/Scripts/js.cookie-1.5.1.min.js"></script>
|
||||
<script src="~/Scripts/moment-with-locales.min.js"></script>
|
||||
<script type="text/javascript" src="~/Scripts/Views/IoTApp.js"></script>
|
||||
@Styles.Render("~/Content/css/vendor")
|
||||
@Styles.Render("~/Content/css")
|
||||
|
@ -124,6 +126,6 @@
|
|||
<script src="~/Scripts/controls.js"></script>
|
||||
@RenderSection("scripts", required: false)
|
||||
|
||||
@Scripts.Render("~/bundles/bootstrap")
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -274,6 +274,7 @@
|
|||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Strings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="App_Start\DataBinders.cs" />
|
||||
<Compile Include="App_Start\Startup.Json.cs" />
|
||||
<Compile Include="App_Start\Startup.Autofac.cs" />
|
||||
<Compile Include="App_Start\Startup.WebApi.cs" />
|
||||
|
@ -303,10 +304,12 @@
|
|||
<Compile Include="Models\ActionPropertiesModel.cs" />
|
||||
<Compile Include="Models\AlertHistoryDeviceModel.cs" />
|
||||
<Compile Include="Models\EditDeviceRuleModel.cs" />
|
||||
<Compile Include="Models\ScheduleDeviceMethodModel.cs" />
|
||||
<Compile Include="Models\LanguageModel.cs" />
|
||||
<Compile Include="Models\NamedDeviceJob.cs" />
|
||||
<Compile Include="Models\NamedJobResponseModel.cs" />
|
||||
<Compile Include="Models\ScheduleJobModel.cs" />
|
||||
<Compile Include="Models\ScheduleJobModel.cs" />
|
||||
<Compile Include="Models\ScheduleTwinUpdateModel.cs" />
|
||||
<Compile Include="Models\SimInformationViewModel.cs" />
|
||||
<Compile Include="Models\UpdateActionModel.cs" />
|
||||
<Compile Include="Models\AlertHistoryResultsModel.cs" />
|
||||
|
@ -416,6 +419,9 @@
|
|||
<Content Include="Content\img\sort_desc.png" />
|
||||
<Content Include="Content\img\sort_desc_disabled.png" />
|
||||
<Content Include="Content\styles\main.css" />
|
||||
<Content Include="Content\styles\main.min.css">
|
||||
<DependentUpon>main.css</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="Content\styles\visuals.min.css" />
|
||||
<Content Include="Content\styles\bootstrap\dropdowns.less" />
|
||||
<Content Include="Content\styles\bootstrap\bootstrap.less" />
|
||||
|
@ -458,7 +464,11 @@
|
|||
<Content Include="Content\styles\bootstrap\mixins\text-emphasis.less" />
|
||||
<Content Include="Content\styles\bootstrap\mixins\text-overflow.less" />
|
||||
<Content Include="Content\styles\bootstrap\mixins\vendor-prefixes.less" />
|
||||
<Content Include="Content\styles\bootstrap-datetimepicker-build.less" />
|
||||
<Content Include="Content\styles\_bootstrap-datetimepicker.less" />
|
||||
<Content Include="Content\styles\bootstrap\glyphicon.less" />
|
||||
<None Include="Scripts\jquery-2.2.3.intellisense.js" />
|
||||
<Content Include="Scripts\bootstrap-datetimepicker.min.js" />
|
||||
<Content Include="Scripts\bootstrap.min.js" />
|
||||
<Content Include="Scripts\controls.js" />
|
||||
<Content Include="Scripts\jquery-2.2.3.js" />
|
||||
|
@ -571,6 +581,8 @@
|
|||
<Content Include="Scripts\Views\Device\EditDeviceProperties.js" />
|
||||
<Content Include="Scripts\Views\Device\RemoveDevice.js" />
|
||||
<Content Include="Scripts\Views\IoTApp.js" />
|
||||
<Content Include="Scripts\Views\Job\ScheduleDeviceMethod.js" />
|
||||
<Content Include="Scripts\Views\Job\ScheduleTwinUpdate.js" />
|
||||
<Content Include="Scripts\_references.js" />
|
||||
<Content Include="Scripts\jquery.dataTables.min.js" />
|
||||
<Content Include="Scripts\jquery.unobtrusive-ajax.js" />
|
||||
|
@ -653,6 +665,8 @@
|
|||
<Content Include="Views\Advanced\_IccidAssociation.cshtml" />
|
||||
<Content Include="Views\Job\_ScheduleJob.cshtml" />
|
||||
<Content Include="Views\Device\_DeviceListColumns.cshtml" />
|
||||
<Content Include="Views\Job\ScheduleTwinUpdate.cshtml" />
|
||||
<Content Include="Views\Job\ScheduleDeviceMethod.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="packages.config">
|
||||
|
@ -783,9 +797,11 @@
|
|||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.6.3\build\Microsoft.Azure.DocumentDB.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Azure.DocumentDB.1.6.3\build\Microsoft.Azure.DocumentDB.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\BuildWebCompiler.1.11.319\build\BuildWebCompiler.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\BuildWebCompiler.1.11.319\build\BuildWebCompiler.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\packages\Microsoft.Web.WebJobs.Publish.1.0.11\tools\webjobs.targets" Condition="Exists('..\..\packages\Microsoft.Web.WebJobs.Publish.1.0.11\tools\webjobs.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.Azure.DocumentDB.1.6.3\build\Microsoft.Azure.DocumentDB.targets" Condition="Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.6.3\build\Microsoft.Azure.DocumentDB.targets')" />
|
||||
<Import Project="..\..\packages\BuildWebCompiler.1.11.319\build\BuildWebCompiler.targets" Condition="Exists('..\..\packages\BuildWebCompiler.1.11.319\build\BuildWebCompiler.targets')" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<package id="Autofac.Owin" version="3.1.0" targetFramework="net451" />
|
||||
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net451" />
|
||||
<package id="Autofac.WebApi2.Owin" version="3.3.0" targetFramework="net451" />
|
||||
<package id="BuildWebCompiler" version="1.11.319" targetFramework="net451" />
|
||||
<package id="dotless" version="1.5.2" targetFramework="net451" />
|
||||
<package id="DotNetty.Buffers-signed" version="0.3.1" targetFramework="net451" />
|
||||
<package id="DotNetty.Codecs.Mqtt-signed" version="0.3.1" targetFramework="net451" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче