Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
74b87f02
Commit
74b87f02
authored
Nov 10, 2017
by
Clement Ho
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Backport of add-epic-sidebar
parent
e4df83d0
Changes
17
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
849 additions
and
14 deletions
+849
-14
app/assets/javascripts/lib/utils/datetime_utility.js
app/assets/javascripts/lib/utils/datetime_utility.js
+14
-1
app/assets/javascripts/lib/utils/text_utility.js
app/assets/javascripts/lib/utils/text_utility.js
+4
-0
app/assets/javascripts/vue_shared/components/pikaday.vue
app/assets/javascripts/vue_shared/components/pikaday.vue
+79
-0
app/assets/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon.vue
...vue_shared/components/sidebar/collapsed_calendar_icon.vue
+46
-0
app/assets/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue
...ared/components/sidebar/collapsed_grouped_date_picker.vue
+109
-0
app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue
...javascripts/vue_shared/components/sidebar/date_picker.vue
+163
-0
app/assets/javascripts/vue_shared/components/sidebar/toggle_sidebar.vue
...ascripts/vue_shared/components/sidebar/toggle_sidebar.vue
+30
-0
app/assets/stylesheets/framework/buttons.scss
app/assets/stylesheets/framework/buttons.scss
+23
-0
app/assets/stylesheets/framework/sidebar.scss
app/assets/stylesheets/framework/sidebar.scss
+23
-2
app/assets/stylesheets/pages/issuable.scss
app/assets/stylesheets/pages/issuable.scss
+27
-2
spec/javascripts/datetime_utility_spec.js
spec/javascripts/datetime_utility_spec.js
+17
-5
spec/javascripts/lib/utils/text_utility_spec.js
spec/javascripts/lib/utils/text_utility_spec.js
+10
-4
spec/javascripts/vue_shared/components/pikaday_spec.js
spec/javascripts/vue_shared/components/pikaday_spec.js
+29
-0
spec/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon_spec.js
...shared/components/sidebar/collapsed_calendar_icon_spec.js
+35
-0
spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js
.../components/sidebar/collapsed_grouped_date_picker_spec.js
+91
-0
spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js
...scripts/vue_shared/components/sidebar/date_picker_spec.js
+117
-0
spec/javascripts/vue_shared/components/sidebar/toggle_sidebar_spec.js
...ipts/vue_shared/components/sidebar/toggle_sidebar_spec.js
+32
-0
No files found.
app/assets/javascripts/lib/utils/datetime_utility.js
View file @
74b87f02
...
@@ -135,7 +135,6 @@ window.dateFormat = dateFormat;
...
@@ -135,7 +135,6 @@ window.dateFormat = dateFormat;
* @param {Number} seconds
* @param {Number} seconds
* @return {String}
* @return {String}
*/
*/
// eslint-disable-next-line import/prefer-default-export
export
function
timeIntervalInWords
(
intervalInSeconds
)
{
export
function
timeIntervalInWords
(
intervalInSeconds
)
{
const
secondsInteger
=
parseInt
(
intervalInSeconds
,
10
);
const
secondsInteger
=
parseInt
(
intervalInSeconds
,
10
);
const
minutes
=
Math
.
floor
(
secondsInteger
/
60
);
const
minutes
=
Math
.
floor
(
secondsInteger
/
60
);
...
@@ -149,3 +148,17 @@ export function timeIntervalInWords(intervalInSeconds) {
...
@@ -149,3 +148,17 @@ export function timeIntervalInWords(intervalInSeconds) {
}
}
return
text
;
return
text
;
}
}
export
function
dateInWords
(
date
,
abbreviated
=
false
)
{
if
(
!
date
)
return
date
;
const
month
=
date
.
getMonth
();
const
year
=
date
.
getFullYear
();
const
monthNames
=
[
s__
(
'
January
'
),
s__
(
'
February
'
),
s__
(
'
March
'
),
s__
(
'
April
'
),
s__
(
'
May
'
),
s__
(
'
June
'
),
s__
(
'
July
'
),
s__
(
'
August
'
),
s__
(
'
September
'
),
s__
(
'
October
'
),
s__
(
'
November
'
),
s__
(
'
December
'
)];
const
monthNamesAbbr
=
[
s__
(
'
Jan
'
),
s__
(
'
Feb
'
),
s__
(
'
Mar
'
),
s__
(
'
Apr
'
),
s__
(
'
May
'
),
s__
(
'
Jun
'
),
s__
(
'
Jul
'
),
s__
(
'
Aug
'
),
s__
(
'
Sep
'
),
s__
(
'
Oct
'
),
s__
(
'
Nov
'
),
s__
(
'
Dec
'
)];
const
monthName
=
abbreviated
?
monthNamesAbbr
[
month
]
:
monthNames
[
month
];
return
`
${
monthName
}
${
date
.
getDate
()}
,
${
year
}
`
;
}
app/assets/javascripts/lib/utils/text_utility.js
View file @
74b87f02
...
@@ -24,6 +24,10 @@ export function highCountTrim(count) {
...
@@ -24,6 +24,10 @@ export function highCountTrim(count) {
return
count
>
99
?
'
99+
'
:
count
;
return
count
>
99
?
'
99+
'
:
count
;
}
}
export
function
capitalizeFirstCharacter
(
text
)
{
return
`
${
text
[
0
].
toUpperCase
()}${
text
.
slice
(
1
)}
`
;
}
gl
.
text
.
randomString
=
function
()
{
gl
.
text
.
randomString
=
function
()
{
return
Math
.
random
().
toString
(
36
).
substring
(
7
);
return
Math
.
random
().
toString
(
36
).
substring
(
7
);
};
};
...
...
app/assets/javascripts/vue_shared/components/pikaday.vue
0 → 100644
View file @
74b87f02
<
script
>
import
Pikaday
from
'
pikaday
'
;
import
{
parsePikadayDate
,
pikadayToString
}
from
'
../../lib/utils/datefix
'
;
export
default
{
name
:
'
datePicker
'
,
props
:
{
label
:
{
type
:
String
,
required
:
false
,
default
:
'
Date picker
'
,
},
selectedDate
:
{
type
:
Date
,
required
:
false
,
},
minDate
:
{
type
:
Date
,
required
:
false
,
},
maxDate
:
{
type
:
Date
,
required
:
false
,
},
},
methods
:
{
selected
(
dateText
)
{
this
.
$emit
(
'
newDateSelected
'
,
this
.
calendar
.
toString
(
dateText
));
},
toggled
()
{
this
.
$emit
(
'
hidePicker
'
);
},
},
mounted
()
{
this
.
calendar
=
new
Pikaday
({
field
:
this
.
$el
.
querySelector
(
'
.dropdown-menu-toggle
'
),
theme
:
'
gitlab-theme animate-picker
'
,
format
:
'
yyyy-mm-dd
'
,
container
:
this
.
$el
,
defaultDate
:
this
.
selectedDate
,
setDefaultDate
:
!!
this
.
selectedDate
,
minDate
:
this
.
minDate
,
maxDate
:
this
.
maxDate
,
parse
:
dateString
=>
parsePikadayDate
(
dateString
),
toString
:
date
=>
pikadayToString
(
date
),
onSelect
:
this
.
selected
.
bind
(
this
),
onClose
:
this
.
toggled
.
bind
(
this
),
});
this
.
$el
.
append
(
this
.
calendar
.
el
);
this
.
calendar
.
show
();
},
beforeDestroy
()
{
this
.
calendar
.
destroy
();
},
};
</
script
>
<
template
>
<div
class=
"pikaday-container"
>
<div
class=
"dropdown open"
>
<button
type=
"button"
class=
"dropdown-menu-toggle"
data-toggle=
"dropdown"
@
click=
"toggled"
>
<span
class=
"dropdown-toggle-text"
>
{{
label
}}
</span>
<i
class=
"fa fa-chevron-down"
aria-hidden=
"true"
>
</i>
</button>
</div>
</div>
</
template
>
app/assets/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon.vue
0 → 100644
View file @
74b87f02
<
script
>
export
default
{
name
:
'
collapsedCalendarIcon
'
,
props
:
{
containerClass
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
text
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
showIcon
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
},
methods
:
{
click
()
{
this
.
$emit
(
'
click
'
);
},
},
};
</
script
>
<
template
>
<div
:class=
"containerClass"
@
click=
"click"
>
<i
v-if=
"showIcon"
class=
"fa fa-calendar"
aria-hidden=
"true"
>
</i>
<slot>
<span>
{{
text
}}
</span>
</slot>
</div>
</
template
>
app/assets/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue
0 → 100644
View file @
74b87f02
<
script
>
import
{
dateInWords
}
from
'
../../../lib/utils/datetime_utility
'
;
import
toggleSidebar
from
'
./toggle_sidebar.vue
'
;
import
collapsedCalendarIcon
from
'
./collapsed_calendar_icon.vue
'
;
export
default
{
name
:
'
sidebarCollapsedGroupedDatePicker
'
,
props
:
{
collapsed
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
showToggleSidebar
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
minDate
:
{
type
:
Date
,
required
:
false
,
},
maxDate
:
{
type
:
Date
,
required
:
false
,
},
disableClickableIcons
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
components
:
{
toggleSidebar
,
collapsedCalendarIcon
,
},
computed
:
{
hasMinAndMaxDates
()
{
return
this
.
minDate
&&
this
.
maxDate
;
},
hasNoMinAndMaxDates
()
{
return
!
this
.
minDate
&&
!
this
.
maxDate
;
},
showMinDateBlock
()
{
return
this
.
minDate
||
this
.
hasNoMinAndMaxDates
;
},
showFromText
()
{
return
!
this
.
maxDate
&&
this
.
minDate
;
},
iconClass
()
{
const
disabledClass
=
this
.
disableClickableIcons
?
'
disabled
'
:
''
;
return
`block sidebar-collapsed-icon calendar-icon
${
disabledClass
}
`
;
},
},
methods
:
{
toggleSidebar
()
{
this
.
$emit
(
'
toggleCollapse
'
);
},
dateText
(
dateType
=
'
min
'
)
{
const
date
=
this
[
`
${
dateType
}
Date`
];
const
dateWords
=
dateInWords
(
date
,
true
);
const
parsedDateWords
=
dateWords
?
dateWords
.
replace
(
'
,
'
,
''
)
:
dateWords
;
return
date
?
parsedDateWords
:
'
None
'
;
},
},
};
</
script
>
<
template
>
<div
class=
"block sidebar-grouped-item"
>
<div
v-if=
"showToggleSidebar"
class=
"issuable-sidebar-header"
>
<toggle-sidebar
:collapsed=
"collapsed"
@
toggle=
"toggleSidebar"
/>
</div>
<collapsed-calendar-icon
v-if=
"showMinDateBlock"
:container-class=
"iconClass"
@
click=
"toggleSidebar"
>
<span
class=
"sidebar-collapsed-value"
>
<span
v-if=
"showFromText"
>
From
</span>
<span>
{{
dateText
(
'
min
'
)
}}
</span>
</span>
</collapsed-calendar-icon>
<div
v-if=
"hasMinAndMaxDates"
class=
"text-center sidebar-collapsed-divider"
>
-
</div>
<collapsed-calendar-icon
v-if=
"maxDate"
:container-class=
"iconClass"
:show-icon=
"!minDate"
@
click=
"toggleSidebar"
>
<span
class=
"sidebar-collapsed-value"
>
<span
v-if=
"!minDate"
>
Until
</span>
<span>
{{
dateText
(
'
max
'
)
}}
</span>
</span>
</collapsed-calendar-icon>
</div>
</
template
>
app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue
0 → 100644
View file @
74b87f02
<
script
>
import
datePicker
from
'
../pikaday.vue
'
;
import
loadingIcon
from
'
../loading_icon.vue
'
;
import
toggleSidebar
from
'
./toggle_sidebar.vue
'
;
import
collapsedCalendarIcon
from
'
./collapsed_calendar_icon.vue
'
;
import
{
dateInWords
}
from
'
../../../lib/utils/datetime_utility
'
;
export
default
{
name
:
'
sidebarDatePicker
'
,
props
:
{
collapsed
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
showToggleSidebar
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
isLoading
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
editable
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
label
:
{
type
:
String
,
required
:
false
,
default
:
'
Date picker
'
,
},
selectedDate
:
{
type
:
Date
,
required
:
false
,
},
minDate
:
{
type
:
Date
,
required
:
false
,
},
maxDate
:
{
type
:
Date
,
required
:
false
,
},
},
data
()
{
return
{
editing
:
false
,
};
},
components
:
{
datePicker
,
toggleSidebar
,
loadingIcon
,
collapsedCalendarIcon
,
},
computed
:
{
selectedAndEditable
()
{
return
this
.
selectedDate
&&
this
.
editable
;
},
selectedDateWords
()
{
return
dateInWords
(
this
.
selectedDate
,
true
);
},
collapsedText
()
{
return
this
.
selectedDateWords
?
this
.
selectedDateWords
:
'
None
'
;
},
},
methods
:
{
stopEditing
()
{
this
.
editing
=
false
;
},
toggleDatePicker
()
{
this
.
editing
=
!
this
.
editing
;
},
newDateSelected
(
date
=
null
)
{
this
.
date
=
date
;
this
.
editing
=
false
;
this
.
$emit
(
'
saveDate
'
,
date
);
},
toggleSidebar
()
{
this
.
$emit
(
'
toggleCollapse
'
);
},
},
};
</
script
>
<
template
>
<div
class=
"block"
>
<div
class=
"issuable-sidebar-header"
>
<toggle-sidebar
:collapsed=
"collapsed"
@
toggle=
"toggleSidebar"
/>
</div>
<collapsed-calendar-icon
class=
"sidebar-collapsed-icon"
:text=
"collapsedText"
/>
<div
class=
"title"
>
{{
label
}}
<loading-icon
v-if=
"isLoading"
:inline=
"true"
/>
<div
class=
"pull-right"
>
<button
v-if=
"editable && !editing"
type=
"button"
class=
"btn-blank btn-link btn-primary-hover-link btn-sidebar-action"
@
click=
"toggleDatePicker"
>
Edit
</button>
<toggle-sidebar
v-if=
"showToggleSidebar"
:collapsed=
"collapsed"
@
toggle=
"toggleSidebar"
/>
</div>
</div>
<div
class=
"value"
>
<date-picker
v-if=
"editing"
:selected-date=
"selectedDate"
:min-date=
"minDate"
:max-date=
"maxDate"
:label=
"label"
@
newDateSelected=
"newDateSelected"
@
hidePicker=
"stopEditing"
/>
<span
v-else
class=
"value-content"
>
<template
v-if=
"selectedDate"
>
<strong>
{{
selectedDateWords
}}
</strong>
<span
v-if=
"selectedAndEditable"
class=
"no-value"
>
-
<button
type=
"button"
class=
"btn-blank btn-link btn-secondary-hover-link"
@
click=
"newDateSelected(null)"
>
remove
</button>
</span>
</
template
>
<span
v-else
class=
"no-value"
>
None
</span>
</span>
</div>
</div>
</template>
app/assets/javascripts/vue_shared/components/sidebar/toggle_sidebar.vue
0 → 100644
View file @
74b87f02
<
script
>
export
default
{
name
:
'
toggleSidebar
'
,
props
:
{
collapsed
:
{
type
:
Boolean
,
required
:
true
,
},
},
methods
:
{
toggle
()
{
this
.
$emit
(
'
toggle
'
);
},
},
};
</
script
>
<
template
>
<button
type=
"button"
class=
"btn btn-blank gutter-toggle btn-sidebar-action"
@
click=
"toggle"
>
<i
aria-label=
"toggle collapse"
class=
"fa"
:class=
"
{ 'fa-angle-double-right': !collapsed, 'fa-angle-double-left': collapsed }"
>
</i>
</button>
</
template
>
app/assets/stylesheets/framework/buttons.scss
View file @
74b87f02
...
@@ -408,6 +408,7 @@
...
@@ -408,6 +408,7 @@
padding
:
0
;
padding
:
0
;
background
:
transparent
;
background
:
transparent
;
border
:
0
;
border
:
0
;
border-radius
:
0
;
&
:hover
,
&
:hover
,
&
:active
,
&
:active
,
...
@@ -417,3 +418,25 @@
...
@@ -417,3 +418,25 @@
box-shadow
:
none
;
box-shadow
:
none
;
}
}
}
}
.btn-link.btn-secondary-hover-link
{
color
:
$gl-text-color-secondary
;
&
:hover
,
&
:active
,
&
:focus
{
color
:
$gl-link-color
;
text-decoration
:
none
;
}
}
.btn-link.btn-primary-hover-link
{
color
:
inherit
;
&
:hover
,
&
:active
,
&
:focus
{
color
:
$gl-link-color
;
text-decoration
:
none
;
}
}
app/assets/stylesheets/framework/sidebar.scss
View file @
74b87f02
...
@@ -43,11 +43,13 @@
...
@@ -43,11 +43,13 @@
}
}
.sidebar-collapsed-icon
{
.sidebar-collapsed-icon
{
cursor
:
pointer
;
.btn
{
.btn
{
background-color
:
$gray-light
;
background-color
:
$gray-light
;
}
}
&
:not
(
.disabled
)
{
cursor
:
pointer
;
}
}
}
}
}
...
@@ -55,6 +57,10 @@
...
@@ -55,6 +57,10 @@
padding-right
:
0
;
padding-right
:
0
;
z-index
:
300
;
z-index
:
300
;
.btn-sidebar-action
{
display
:
inline-flex
;
}
@media
(
min-width
:
$screen-sm-min
)
and
(
max-width
:
$screen-sm-max
)
{
@media
(
min-width
:
$screen-sm-min
)
and
(
max-width
:
$screen-sm-max
)
{
&
:not
(
.wiki-sidebar
)
:not
(
.build-sidebar
)
:not
(
.issuable-bulk-update-sidebar
)
.content-wrapper
{
&
:not
(
.wiki-sidebar
)
:not
(
.build-sidebar
)
:not
(
.issuable-bulk-update-sidebar
)
.content-wrapper
{
padding-right
:
$gutter_collapsed_width
;
padding-right
:
$gutter_collapsed_width
;
...
@@ -136,3 +142,18 @@
...
@@ -136,3 +142,18 @@
.issuable-sidebar
{
.issuable-sidebar
{
@include
new-style-dropdown
;
@include
new-style-dropdown
;
}
}
.pikaday-container
{
.pika-single
{
margin-top
:
2px
;
width
:
250px
;
}
.dropdown-menu-toggle
{
line-height
:
20px
;
}
}
.sidebar-collapsed-icon
.sidebar-collapsed-value
{
font-size
:
12px
;
}
app/assets/stylesheets/pages/issuable.scss
View file @
74b87f02
...
@@ -284,10 +284,15 @@
...
@@ -284,10 +284,15 @@
font-weight
:
$gl-font-weight-normal
;
font-weight
:
$gl-font-weight-normal
;
}
}
.no-value
{
.no-value
,
.btn-secondary-hover-link
{
color
:
$gl-text-color-secondary
;
color
:
$gl-text-color-secondary
;
}
}
.btn-secondary-hover-link
:hover
{
color
:
$gl-link-color
;
}
.sidebar-collapsed-icon
{
.sidebar-collapsed-icon
{
display
:
none
;
display
:
none
;
}
}
...
@@ -295,6 +300,8 @@
...
@@ -295,6 +300,8 @@
.gutter-toggle
{
.gutter-toggle
{
margin-top
:
7px
;
margin-top
:
7px
;
border-left
:
1px
solid
$border-gray-normal
;
border-left
:
1px
solid
$border-gray-normal
;
padding-left
:
0
;
text-align
:
center
;
}
}
.title
.gutter-toggle
{
.title
.gutter-toggle
{
...
@@ -367,7 +374,7 @@
...
@@ -367,7 +374,7 @@
fill
:
$issuable-sidebar-color
;
fill
:
$issuable-sidebar-color
;
}
}
&
:hover
,
&
:hover
:not
(
.disabled
)
,
&
:hover
.todo-undone
{
&
:hover
.todo-undone
{
color
:
$gl-text-color
;
color
:
$gl-text-color
;
...
@@ -908,3 +915,21 @@
...
@@ -908,3 +915,21 @@
margin
:
0
3px
;
margin
:
0
3px
;
}
}
}
}
.right-sidebar-collapsed
{
.sidebar-grouped-item
{
.sidebar-collapsed-icon
{
margin-bottom
:
0
;
}
.sidebar-collapsed-divider
{
line-height
:
5px
;
font-size
:
12px
;
color
:
$theme-gray-700
;
+
.sidebar-collapsed-icon
{
padding-top
:
0
;
}
}
}
}
spec/javascripts/datetime_utility_spec.js
View file @
74b87f02
import
{
timeIntervalInWords
}
from
'
~/lib/utils/datetime_utility
'
;
import
*
as
datetimeUtility
from
'
~/lib/utils/datetime_utility
'
;
(()
=>
{
(()
=>
{
describe
(
'
Date time utils
'
,
()
=>
{
describe
(
'
Date time utils
'
,
()
=>
{
...
@@ -89,10 +89,22 @@ import { timeIntervalInWords } from '~/lib/utils/datetime_utility';
...
@@ -89,10 +89,22 @@ import { timeIntervalInWords } from '~/lib/utils/datetime_utility';
describe
(
'
timeIntervalInWords
'
,
()
=>
{
describe
(
'
timeIntervalInWords
'
,
()
=>
{
it
(
'
should return string with number of minutes and seconds
'
,
()
=>
{
it
(
'
should return string with number of minutes and seconds
'
,
()
=>
{
expect
(
timeIntervalInWords
(
9.54
)).
toEqual
(
'
9 seconds
'
);
expect
(
datetimeUtility
.
timeIntervalInWords
(
9.54
)).
toEqual
(
'
9 seconds
'
);
expect
(
timeIntervalInWords
(
1
)).
toEqual
(
'
1 second
'
);
expect
(
datetimeUtility
.
timeIntervalInWords
(
1
)).
toEqual
(
'
1 second
'
);
expect
(
timeIntervalInWords
(
200
)).
toEqual
(
'
3 minutes 20 seconds
'
);
expect
(
datetimeUtility
.
timeIntervalInWords
(
200
)).
toEqual
(
'
3 minutes 20 seconds
'
);
expect
(
timeIntervalInWords
(
6008
)).
toEqual
(
'
100 minutes 8 seconds
'
);
expect
(
datetimeUtility
.
timeIntervalInWords
(
6008
)).
toEqual
(
'
100 minutes 8 seconds
'
);
});
});
describe
(
'
dateInWords
'
,
()
=>
{
const
date
=
new
Date
(
'
07/01/2016
'
);
it
(
'
should return date in words
'
,
()
=>
{
expect
(
datetimeUtility
.
dateInWords
(
date
)).
toEqual
(
'
July 1, 2016
'
);
});
it
(
'
should return abbreviated month name
'
,
()
=>
{
expect
(
datetimeUtility
.
dateInWords
(
date
,
true
)).
toEqual
(
'
Jul 1, 2016
'
);
});
});
});
});
})();
})();
spec/javascripts/lib/utils/text_utility_spec.js
View file @
74b87f02
import
{
highCountTrim
}
from
'
~/lib/utils/text_utility
'
;
import
*
as
textUtility
from
'
~/lib/utils/text_utility
'
;
describe
(
'
text_utility
'
,
()
=>
{
describe
(
'
text_utility
'
,
()
=>
{
describe
(
'
gl.text.getTextWidth
'
,
()
=>
{
describe
(
'
gl.text.getTextWidth
'
,
()
=>
{
...
@@ -37,12 +37,18 @@ describe('text_utility', () => {
...
@@ -37,12 +37,18 @@ describe('text_utility', () => {
describe
(
'
highCountTrim
'
,
()
=>
{
describe
(
'
highCountTrim
'
,
()
=>
{
it
(
'
returns 99+ for count >= 100
'
,
()
=>
{
it
(
'
returns 99+ for count >= 100
'
,
()
=>
{
expect
(
highCountTrim
(
105
)).
toBe
(
'
99+
'
);
expect
(
textUtility
.
highCountTrim
(
105
)).
toBe
(
'
99+
'
);
expect
(
highCountTrim
(
100
)).
toBe
(
'
99+
'
);
expect
(
textUtility
.
highCountTrim
(
100
)).
toBe
(
'
99+
'
);
});
});
it
(
'
returns exact number for count < 100
'
,
()
=>
{
it
(
'
returns exact number for count < 100
'
,
()
=>
{
expect
(
highCountTrim
(
45
)).
toBe
(
45
);
expect
(
textUtility
.
highCountTrim
(
45
)).
toBe
(
45
);
});
});
describe
(
'
capitalizeFirstCharacter
'
,
()
=>
{
it
(
'
returns string with first letter capitalized
'
,
()
=>
{
expect
(
textUtility
.
capitalizeFirstCharacter
(
'
gitlab
'
)).
toEqual
(
'
Gitlab
'
);
});
});
});
});
...
...
spec/javascripts/vue_shared/components/pikaday_spec.js
0 → 100644
View file @
74b87f02
import
Vue
from
'
vue
'
;
import
datePicker
from
'
~/vue_shared/components/pikaday.vue
'
;
import
mountComponent
from
'
../../helpers/vue_mount_component_helper
'
;
describe
(
'
datePicker
'
,
()
=>
{
let
vm
;
beforeEach
(()
=>
{
const
DatePicker
=
Vue
.
extend
(
datePicker
);
vm
=
mountComponent
(
DatePicker
,
{
label
:
'
label
'
,
});
});
it
(
'
should render label text
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.dropdown-toggle-text
'
).
innerText
.
trim
()).
toEqual
(
'
label
'
);
});
it
(
'
should show calendar
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.pika-single
'
)).
toBeDefined
();
});
it
(
'
should toggle when dropdown is clicked
'
,
()
=>
{
const
hidePicker
=
jasmine
.
createSpy
();
vm
.
$on
(
'
hidePicker
'
,
hidePicker
);
vm
.
$el
.
querySelector
(
'
.dropdown-menu-toggle
'
).
click
();
expect
(
hidePicker
).
toHaveBeenCalled
();
});
});
spec/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon_spec.js
0 → 100644
View file @
74b87f02
import
Vue
from
'
vue
'
;
import
collapsedCalendarIcon
from
'
~/vue_shared/components/sidebar/collapsed_calendar_icon.vue
'
;
import
mountComponent
from
'
../../../helpers/vue_mount_component_helper
'
;
describe
(
'
collapsedCalendarIcon
'
,
()
=>
{
let
vm
;
beforeEach
(()
=>
{
const
CollapsedCalendarIcon
=
Vue
.
extend
(
collapsedCalendarIcon
);
vm
=
mountComponent
(
CollapsedCalendarIcon
,
{
containerClass
:
'
test-class
'
,
text
:
'
text
'
,
showIcon
:
false
,
});
});
it
(
'
should add class to container
'
,
()
=>
{
expect
(
vm
.
$el
.
classList
.
contains
(
'
test-class
'
)).
toEqual
(
true
);
});
it
(
'
should hide calendar icon if showIcon
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.fa-calendar
'
)).
toBeNull
();
});
it
(
'
should render text
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
span
'
).
innerText
.
trim
()).
toEqual
(
'
text
'
);
});
it
(
'
should emit click event when container is clicked
'
,
()
=>
{
const
click
=
jasmine
.
createSpy
();
vm
.
$on
(
'
click
'
,
click
);
vm
.
$el
.
click
();
expect
(
click
).
toHaveBeenCalled
();
});
});
spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js
0 → 100644
View file @
74b87f02
import
Vue
from
'
vue
'
;
import
collapsedGroupedDatePicker
from
'
~/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue
'
;
import
mountComponent
from
'
../../../helpers/vue_mount_component_helper
'
;
describe
(
'
collapsedGroupedDatePicker
'
,
()
=>
{
let
vm
;
beforeEach
(()
=>
{
const
CollapsedGroupedDatePicker
=
Vue
.
extend
(
collapsedGroupedDatePicker
);
vm
=
mountComponent
(
CollapsedGroupedDatePicker
,
{
showToggleSidebar
:
true
,
});
});
it
(
'
should render toggle sidebar if showToggleSidebar
'
,
(
done
)
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.issuable-sidebar-header
'
)).
toBeDefined
();
vm
.
showToggleSidebar
=
false
;
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.issuable-sidebar-header
'
)).
toBeNull
();
done
();
});
});
it
(
'
toggleCollapse events
'
,
()
=>
{
const
toggleCollapse
=
jasmine
.
createSpy
();
beforeEach
((
done
)
=>
{
vm
.
minDate
=
new
Date
(
'
07/17/2016
'
);
Vue
.
nextTick
(
done
);
});
it
(
'
should emit when sidebar is toggled
'
,
()
=>
{
vm
.
$el
.
querySelector
(
'
.gutter-toggle
'
).
click
();
expect
(
toggleCollapse
).
toHaveBeenCalled
();
});
it
(
'
should emit when collapsed-calendar-icon is clicked
'
,
()
=>
{
vm
.
$el
.
querySelector
(
'
.sidebar-collapsed-icon
'
).
click
();
expect
(
toggleCollapse
).
toHaveBeenCalled
();
});
});
describe
(
'
minDate and maxDate
'
,
()
=>
{
beforeEach
((
done
)
=>
{
vm
.
minDate
=
new
Date
(
'
07/17/2016
'
);
vm
.
maxDate
=
new
Date
(
'
07/17/2017
'
);
Vue
.
nextTick
(
done
);
});
it
(
'
should render both collapsed-calendar-icon
'
,
()
=>
{
const
icons
=
vm
.
$el
.
querySelectorAll
(
'
.sidebar-collapsed-icon
'
);
expect
(
icons
.
length
).
toEqual
(
2
);
expect
(
icons
[
0
].
innerText
.
trim
()).
toEqual
(
'
Jul 17 2016
'
);
expect
(
icons
[
1
].
innerText
.
trim
()).
toEqual
(
'
Jul 17 2017
'
);
});
});
describe
(
'
minDate
'
,
()
=>
{
beforeEach
((
done
)
=>
{
vm
.
minDate
=
new
Date
(
'
07/17/2016
'
);
Vue
.
nextTick
(
done
);
});
it
(
'
should render minDate in collapsed-calendar-icon
'
,
()
=>
{
const
icons
=
vm
.
$el
.
querySelectorAll
(
'
.sidebar-collapsed-icon
'
);
expect
(
icons
.
length
).
toEqual
(
1
);
expect
(
icons
[
0
].
innerText
.
trim
()).
toEqual
(
'
From Jul 17 2016
'
);
});
});
describe
(
'
maxDate
'
,
()
=>
{
beforeEach
((
done
)
=>
{
vm
.
maxDate
=
new
Date
(
'
07/17/2017
'
);
Vue
.
nextTick
(
done
);
});
it
(
'
should render maxDate in collapsed-calendar-icon
'
,
()
=>
{
const
icons
=
vm
.
$el
.
querySelectorAll
(
'
.sidebar-collapsed-icon
'
);
expect
(
icons
.
length
).
toEqual
(
1
);
expect
(
icons
[
0
].
innerText
.
trim
()).
toEqual
(
'
Until Jul 17 2017
'
);
});
});
describe
(
'
no dates
'
,
()
=>
{
it
(
'
should render None
'
,
()
=>
{
const
icons
=
vm
.
$el
.
querySelectorAll
(
'
.sidebar-collapsed-icon
'
);
expect
(
icons
.
length
).
toEqual
(
1
);
expect
(
icons
[
0
].
innerText
.
trim
()).
toEqual
(
'
None
'
);
});
});
});
spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js
0 → 100644
View file @
74b87f02
import
Vue
from
'
vue
'
;
import
sidebarDatePicker
from
'
~/vue_shared/components/sidebar/date_picker.vue
'
;
import
mountComponent
from
'
../../../helpers/vue_mount_component_helper
'
;
describe
(
'
sidebarDatePicker
'
,
()
=>
{
let
vm
;
beforeEach
(()
=>
{
const
SidebarDatePicker
=
Vue
.
extend
(
sidebarDatePicker
);
vm
=
mountComponent
(
SidebarDatePicker
,
{
label
:
'
label
'
,
isLoading
:
true
,
});
});
it
(
'
should emit toggleCollapse when collapsed toggle sidebar is clicked
'
,
()
=>
{
const
toggleCollapse
=
jasmine
.
createSpy
();
vm
.
$on
(
'
toggleCollapse
'
,
toggleCollapse
);
vm
.
$el
.
querySelector
(
'
.issuable-sidebar-header .gutter-toggle
'
).
click
();
expect
(
toggleCollapse
).
toHaveBeenCalled
();
});
it
(
'
should render collapsed-calendar-icon
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.sidebar-collapsed-icon
'
)).
toBeDefined
();
});
it
(
'
should render label
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.title
'
).
innerText
.
trim
()).
toEqual
(
'
label
'
);
});
it
(
'
should render loading-icon when isLoading
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.fa-spin
'
)).
toBeDefined
();
});
it
(
'
should render value when not editing
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.value-content
'
)).
toBeDefined
();
});
it
(
'
should render None if there is no selectedDate
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.value-content span
'
).
innerText
.
trim
()).
toEqual
(
'
None
'
);
});
it
(
'
should render date-picker when editing
'
,
(
done
)
=>
{
vm
.
editing
=
true
;
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.pika-label
'
)).
toBeDefined
();
done
();
});
});
describe
(
'
editable
'
,
()
=>
{
beforeEach
((
done
)
=>
{
vm
.
editable
=
true
;
Vue
.
nextTick
(
done
);
});
it
(
'
should render edit button
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.title .btn-blank
'
).
innerText
.
trim
()).
toEqual
(
'
Edit
'
);
});
it
(
'
should enable editing when edit button is clicked
'
,
(
done
)
=>
{
vm
.
isLoading
=
false
;
Vue
.
nextTick
(()
=>
{
vm
.
$el
.
querySelector
(
'
.title .btn-blank
'
).
click
();
expect
(
vm
.
editing
).
toEqual
(
true
);
done
();
});
});
});
it
(
'
should render date if selectedDate
'
,
(
done
)
=>
{
vm
.
selectedDate
=
new
Date
(
'
07/07/2017
'
);
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.value-content strong
'
).
innerText
.
trim
()).
toEqual
(
'
Jul 7, 2017
'
);
done
();
});
});
describe
(
'
selectedDate and editable
'
,
()
=>
{
beforeEach
((
done
)
=>
{
vm
.
selectedDate
=
new
Date
(
'
07/07/2017
'
);
vm
.
editable
=
true
;
Vue
.
nextTick
(
done
);
});
it
(
'
should render remove button if selectedDate and editable
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.value-content .btn-blank
'
).
innerText
.
trim
()).
toEqual
(
'
remove
'
);
});
it
(
'
should emit saveDate when remove button is clicked
'
,
()
=>
{
const
saveDate
=
jasmine
.
createSpy
();
vm
.
$on
(
'
saveDate
'
,
saveDate
);
vm
.
$el
.
querySelector
(
'
.value-content .btn-blank
'
).
click
();
expect
(
saveDate
).
toHaveBeenCalled
();
});
});
describe
(
'
showToggleSidebar
'
,
()
=>
{
beforeEach
((
done
)
=>
{
vm
.
showToggleSidebar
=
true
;
Vue
.
nextTick
(
done
);
});
it
(
'
should render toggle-sidebar when showToggleSidebar
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.title .gutter-toggle
'
)).
toBeDefined
();
});
it
(
'
should emit toggleCollapse when toggle sidebar is clicked
'
,
()
=>
{
const
toggleCollapse
=
jasmine
.
createSpy
();
vm
.
$on
(
'
toggleCollapse
'
,
toggleCollapse
);
vm
.
$el
.
querySelector
(
'
.title .gutter-toggle
'
).
click
();
expect
(
toggleCollapse
).
toHaveBeenCalled
();
});
});
});
spec/javascripts/vue_shared/components/sidebar/toggle_sidebar_spec.js
0 → 100644
View file @
74b87f02
import
Vue
from
'
vue
'
;
import
toggleSidebar
from
'
~/vue_shared/components/sidebar/toggle_sidebar.vue
'
;
import
mountComponent
from
'
../../../helpers/vue_mount_component_helper
'
;
describe
(
'
toggleSidebar
'
,
()
=>
{
let
vm
;
beforeEach
(()
=>
{
const
ToggleSidebar
=
Vue
.
extend
(
toggleSidebar
);
vm
=
mountComponent
(
ToggleSidebar
,
{
collapsed
:
true
,
});
});
it
(
'
should render << when collapsed
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.fa
'
).
classList
.
contains
(
'
fa-angle-double-left
'
)).
toEqual
(
true
);
});
it
(
'
should render >> when collapsed
'
,
()
=>
{
vm
.
collapsed
=
false
;
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.fa
'
).
classList
.
contains
(
'
fa-angle-double-right
'
)).
toEqual
(
true
);
});
});
it
(
'
should emit toggle event when button clicked
'
,
()
=>
{
const
toggle
=
jasmine
.
createSpy
();
vm
.
$on
(
'
toggle
'
,
toggle
);
vm
.
$el
.
click
();
expect
(
toggle
).
toHaveBeenCalled
();
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment