Merge branch 'develop' of github.com:martini/zammad into develop
This commit is contained in:
commit
a30e31bc80
16 changed files with 101 additions and 14 deletions
|
@ -21,12 +21,12 @@ class App.BusinessHours extends Spine.Controller
|
|||
sun: App.i18n.translateInline('Sunday')
|
||||
|
||||
render: =>
|
||||
maxTimeframeDay = _.max @hours, (day) -> day.timeframes.length
|
||||
@updateMaxTimeframes()
|
||||
|
||||
html = App.view('generic/business_hours')
|
||||
days: @days
|
||||
hours: @options.hours
|
||||
maxTimeframes: maxTimeframeDay.timeframes.length
|
||||
maxTimeframes: @maxTimeframes
|
||||
|
||||
@html html
|
||||
|
||||
|
@ -35,13 +35,21 @@ class App.BusinessHours extends Spine.Controller
|
|||
showMeridian: false # meridian = am/pm
|
||||
.on 'changeTime.timepicker', @onTimeChange
|
||||
|
||||
@el.toggleClass 'is-invalid', !@validate()
|
||||
|
||||
updateMaxTimeframes: =>
|
||||
maxTimeframeDay = _.max @hours, (day) -> day.timeframes.length
|
||||
@maxTimeframes = maxTimeframeDay.timeframes.length
|
||||
|
||||
onTimeChange: (event) =>
|
||||
input = @$(event.currentTarget)
|
||||
day = input.attr('data-day')
|
||||
slot = input.attr('data-slot')
|
||||
i = input.attr('data-i')
|
||||
console.log "something changed", event.time
|
||||
@options.hours[day].timeframes[slot][i] = "#{event.time.hours}:#{event.time.minutes}"
|
||||
@options.hours[day].timeframes[slot][i] = event.time.hoursAndMinutes
|
||||
console.log event.time.hoursAndMinutes
|
||||
|
||||
@el.toggleClass 'is-invalid', !@validate()
|
||||
|
||||
addTime: (event) =>
|
||||
day = @$(event.currentTarget).attr('data-day')
|
||||
|
@ -58,3 +66,54 @@ class App.BusinessHours extends Spine.Controller
|
|||
day = checkbox.attr('data-target')
|
||||
@options.hours[day].active = checkbox.prop('checked')
|
||||
@$("[data-day=#{day}]").toggleClass('is-active', checkbox.prop('checked'))
|
||||
|
||||
@el.toggleClass 'is-invalid', !@validate()
|
||||
|
||||
validate: =>
|
||||
for day, hours of @options.hours
|
||||
break if not hours.active
|
||||
|
||||
# edge case: full day
|
||||
if hours.timeframes[0][0] is '00:00' and hours.timeframes[hours.timeframes.length - 1][1] is '00:00'
|
||||
return true
|
||||
|
||||
# check each timeframe
|
||||
for slot in [0..hours.timeframes.length - 1]
|
||||
|
||||
# check if start time is earlier than end time
|
||||
if not @earlier hours.timeframes[slot][0], hours.timeframes[slot][1]
|
||||
return false
|
||||
|
||||
# check if start time of slot is later than end time of slot before
|
||||
if slot > 0 && not @later hours.timeframes[slot][0], hours.timeframes[slot-1][1]
|
||||
return false
|
||||
|
||||
# all passed
|
||||
return true
|
||||
|
||||
later: (a, b) ->
|
||||
# a later b
|
||||
# input 'hh:mm'
|
||||
[ha, ma] = a.split(':').map (val) -> parseInt val, 10
|
||||
[hb, mb] = b.split(':').map (val) -> parseInt val, 10
|
||||
|
||||
if ha > hb
|
||||
return true
|
||||
if ha is hb
|
||||
if ma > mb
|
||||
return true
|
||||
return false
|
||||
|
||||
earlier: (a, b) ->
|
||||
# a earlier than b
|
||||
# input 'hh:mm'
|
||||
|
||||
[ha, ma] = a.split(':').map (val) -> parseInt val, 10
|
||||
[hb, mb] = b.split(':').map (val) -> parseInt val, 10
|
||||
|
||||
if ha < hb
|
||||
return true
|
||||
if ha is hb
|
||||
if ma < mb
|
||||
return true
|
||||
return false
|
|
@ -12,7 +12,8 @@
|
|||
* - automatically jump from hours to minutes when typing in a number
|
||||
* - continue stepping from manually input value
|
||||
* - activate meridian on class 'time--12'
|
||||
* - normalize output hour to 24-hour clock
|
||||
* - normalize output to 24-hour clock
|
||||
* - add hoursAndMinutes
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -142,7 +143,7 @@
|
|||
}
|
||||
} else {
|
||||
if (this.hour <= 0) {
|
||||
this.hour = this.maxHours - 1;
|
||||
this.hour = this.maxHours;
|
||||
} else {
|
||||
this.hour--;
|
||||
}
|
||||
|
@ -950,14 +951,20 @@
|
|||
|
||||
// normalize hour to 24-hour clock
|
||||
var hour = this.hour;
|
||||
if (this.showMeridian && this.meridian == 'PM') {
|
||||
hour += 12;
|
||||
if (this.showMeridian) {
|
||||
if (this.meridian == 'PM' && hour < 12) {
|
||||
hour += 12;
|
||||
}
|
||||
if (this.meridian == 'AM' && hour == 12) {
|
||||
hour = 0;
|
||||
}
|
||||
}
|
||||
|
||||
this.$element.trigger({
|
||||
'type': 'changeTime.timepicker',
|
||||
'time': {
|
||||
'value': this.getTime(),
|
||||
'hoursAndMinutes': this.pad(hour) +':'+ this.pad(this.minute),
|
||||
'hours': hour,
|
||||
'minutes': this.minute,
|
||||
'seconds': this.second,
|
||||
|
@ -966,6 +973,10 @@
|
|||
});
|
||||
},
|
||||
|
||||
pad: function(val) {
|
||||
return val.toString().length === 1 ? '0'+ val : val;
|
||||
},
|
||||
|
||||
updateElement: function() {
|
||||
this.$element.val(this.getTime()).change();
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="u-positionOrigin">
|
||||
<input type="hidden" name="<%- @attribute.name %>" value="<%= @attribute.value %>">
|
||||
<input name="<%- @attribute.name %>_completion" class="ui-autocomplete-input form-control" autocapitalize="off" placeholder="<%- @attribute.placeholder %>" autocomplete="off" role="textbox" aria-autocomplete="list" aria-haspopup="true">
|
||||
<input name="<%- @attribute.name %>_completion" class="user-select form-control" autocapitalize="off" placeholder="<%- @attribute.placeholder %>" autocomplete="off" role="textbox" aria-autocomplete="list" aria-haspopup="true">
|
||||
<%- @Icon('arrow-down', 'dropdown-arrow') %>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1043,6 +1043,10 @@ fieldset > *:not(.form-group) .form-control {
|
|||
.form-group.formGroup--halfSize {
|
||||
width: 50%;
|
||||
float: left;
|
||||
|
||||
.form-control {
|
||||
min-width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.fromGroup--standalone .form-control {
|
||||
|
@ -1068,7 +1072,7 @@ textarea,
|
|||
height: 41px;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 22px;
|
||||
line-height: 27px;
|
||||
color: #555;
|
||||
background: white;
|
||||
border: 1px solid hsl(0, 0%, 90%);
|
||||
|
@ -1081,6 +1085,7 @@ textarea,
|
|||
&.form-control--small {
|
||||
padding: 0 8px;
|
||||
height: 31px;
|
||||
line-height: 29px;
|
||||
}
|
||||
|
||||
&.form-control--inline {
|
||||
|
@ -1089,6 +1094,15 @@ textarea,
|
|||
}
|
||||
}
|
||||
|
||||
input[type=url] {
|
||||
min-width: 400px;
|
||||
}
|
||||
|
||||
.user-select.form-control {
|
||||
padding-right: 35px;
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
input[type=time] {
|
||||
width: auto;
|
||||
padding-left: 6px;
|
||||
|
@ -1196,10 +1210,6 @@ input.time.time--12 {
|
|||
display: none;
|
||||
}
|
||||
|
||||
.form-control.ui-autocomplete-input {
|
||||
padding-right: 35px;
|
||||
}
|
||||
|
||||
.has-error .form-control,
|
||||
.has-error .form-control:focus,
|
||||
.has-error .form-control.focus {
|
||||
|
@ -5858,6 +5868,13 @@ output {
|
|||
background: white;
|
||||
table-layout: auto;
|
||||
|
||||
&.is-invalid {
|
||||
border-radius: 3px;
|
||||
box-shadow:
|
||||
0 0 0 2px white,
|
||||
0 0 0 4px hsl(0,90%,70%);
|
||||
}
|
||||
|
||||
&.settings-list--stretch {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue