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
f9700381
Commit
f9700381
authored
May 05, 2017
by
Eric Eastwood
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add AddIssuableForm
See
https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/1797
parent
c5999f7c
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
318 additions
and
0 deletions
+318
-0
app/assets/javascripts/issuable/related_issues/components/add_issuable_form.vue
.../issuable/related_issues/components/add_issuable_form.vue
+126
-0
app/assets/stylesheets/pages/issuable.scss
app/assets/stylesheets/pages/issuable.scss
+39
-0
spec/javascripts/issuable/related_issues/components/add_issuable_form_spec.js
...uable/related_issues/components/add_issuable_form_spec.js
+153
-0
No files found.
app/assets/javascripts/issuable/related_issues/components/add_issuable_form.vue
0 → 100644
View file @
f9700381
<
script
>
import
eventHub
from
'
../event_hub
'
;
import
IssueToken
from
'
./issue_token.vue
'
;
export
default
{
name
:
'
AddIssuableForm
'
,
props
:
{
inputValue
:
{
type
:
String
,
required
:
true
,
},
addButtonLabel
:
{
type
:
String
,
required
:
true
,
},
pendingIssuables
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
[],
},
},
data
()
{
return
{
isInputFocused
:
false
,
};
},
components
:
{
issueToken
:
IssueToken
,
},
methods
:
{
onInput
()
{
const
value
=
this
.
$refs
.
input
.
value
;
eventHub
.
$emit
(
'
addIssuableFormInput
'
,
value
,
$
(
this
.
$refs
.
input
).
caret
(
'
pos
'
));
},
onFocus
()
{
this
.
isInputFocused
=
true
;
},
onBlur
()
{
this
.
isInputFocused
=
false
;
const
value
=
this
.
$refs
.
input
.
value
;
eventHub
.
$emit
(
'
addIssuableFormBlur
'
,
value
);
},
onInputWrapperClick
()
{
this
.
$refs
.
input
.
focus
();
},
onFormSubmit
()
{
eventHub
.
$emit
(
'
addIssuableFormSubmit
'
);
},
onFormCancel
()
{
eventHub
.
$emit
(
'
addIssuableFormCancel
'
);
},
},
mounted
()
{
const
$input
=
$
(
this
.
$refs
.
input
);
gl
.
GfmAutoComplete
.
setup
(
$input
,
{
issues
:
true
,
});
$input
.
on
(
'
inserted-issues.atwho
'
,
this
.
onInput
);
},
beforeDestroy
()
{
const
$input
=
$
(
this
.
$refs
.
input
);
$input
.
off
(
'
inserted-issues.atwho
'
,
this
.
onInput
);
},
};
</
script
>
<
template
>
<div>
<div
ref=
"issuableFormWrapper"
class=
"add-issuable-form-input-wrapper form-control"
:class=
"
{ focus: isInputFocused }"
role="button"
@click="onInputWrapperClick">
<ul
class=
"add-issuable-form-input-token-list"
>
<li
:key=
"issuable.reference"
v-for=
"issuable in pendingIssuables"
class=
"js-add-issuable-form-token-list-item add-issuable-form-token-list-item"
>
<issue-token
event-namespace=
"pendingIssuable"
:reference=
"issuable.reference"
:display-reference=
"issuable.displayReference"
:title=
"issuable.title"
:path=
"issuable.path"
:state=
"issuable.state"
:fetch-status=
"issuable.fetchStatus"
:can-remove=
"true"
/>
</li>
<li
class=
"add-issuable-form-input-list-item"
>
<input
ref=
"input"
type=
"text"
class=
"add-issuable-form-input"
:value=
"inputValue"
placeholder=
"Search issues..."
@
input=
"onInput"
@
focus=
"onFocus"
@
blur=
"onBlur"
/>
</li>
</ul>
</div>
<div
class=
"clearfix prepend-top-10"
>
<button
ref=
"addButton"
type=
"button"
class=
"btn btn-new pull-left"
@
click=
"onFormSubmit"
>
{{
addButtonLabel
}}
</button>
<button
type=
"button"
class=
"btn btn-default pull-right"
@
click=
"onFormCancel"
>
Cancel
</button>
</div>
</div>
</
template
>
app/assets/stylesheets/pages/issuable.scss
View file @
f9700381
...
...
@@ -727,3 +727,42 @@
}
}
}
.add-issuable-form-input-wrapper
{
height
:
auto
;
padding
:
$gl-vert-padding
$gl-vert-padding
0
$gl-input-padding
;
&
.focus
,
&
.focus
:hover
{
border-color
:
$dropdown-input-focus-border
;
box-shadow
:
0
0
4px
$search-input-focus-shadow-color
;
}
}
.add-issuable-form-input-token-list
{
display
:
flex
;
flex-wrap
:
wrap
;
list-style
:
none
;
margin-bottom
:
0
;
padding-left
:
0
;
}
.add-issuable-form-token-list-item
{
margin-bottom
:
$gl-vert-padding
;
margin-right
:
1em
;
}
.add-issuable-form-input-list-item
{
flex
:
1
;
min-width
:
200px
;
margin-bottom
:
$gl-vert-padding
;
}
.add-issuable-form-input
{
width
:
100%
;
border
:
0
;
&
:focus
{
outline
:
none
;
}
}
spec/javascripts/issuable/related_issues/components/add_issuable_form_spec.js
0 → 100644
View file @
f9700381
import
Vue
from
'
vue
'
;
import
eventHub
from
'
~/issuable/related_issues/event_hub
'
;
import
addIssuableForm
from
'
~/issuable/related_issues/components/add_issuable_form.vue
'
;
const
issuable1
=
{
reference
:
'
foo/bar#123
'
,
title
:
'
some title
'
,
path
:
'
/foo/bar/issues/123
'
,
state
:
'
opened
'
,
};
const
issuable2
=
{
reference
:
'
foo/bar#124
'
,
title
:
'
some other thing
'
,
path
:
'
/foo/bar/issues/124
'
,
state
:
'
opened
'
,
};
describe
(
'
AddIssuableForm
'
,
()
=>
{
let
AddIssuableForm
;
let
vm
;
beforeEach
(()
=>
{
AddIssuableForm
=
Vue
.
extend
(
addIssuableForm
);
});
afterEach
(()
=>
{
if
(
vm
)
{
vm
.
$destroy
();
}
});
describe
(
'
with data
'
,
()
=>
{
const
inputValue
=
'
foo #123
'
;
const
addButtonLabel
=
'
Add issuable
'
;
beforeEach
(()
=>
{
vm
=
new
AddIssuableForm
({
propsData
:
{
inputValue
,
addButtonLabel
,
pendingIssuables
:
[
issuable1
,
issuable2
,
],
},
}).
$mount
();
});
it
(
'
should put button label in place
'
,
()
=>
{
expect
(
vm
.
$refs
.
addButton
.
textContent
.
trim
()).
toEqual
(
addButtonLabel
);
});
it
(
'
should put input value in place
'
,
()
=>
{
expect
(
vm
.
$refs
.
input
.
value
).
toEqual
(
inputValue
);
});
it
(
'
should render pending issuables items
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
.js-add-issuable-form-token-list-item
'
).
length
).
toEqual
(
2
);
});
});
describe
(
'
methods
'
,
()
=>
{
let
addIssuableFormInputSpy
;
let
addIssuableFormBlurSpy
;
let
addIssuableFormSubmitSpy
;
let
addIssuableFormCancelSpy
;
beforeEach
(()
=>
{
addIssuableFormInputSpy
=
jasmine
.
createSpy
(
'
spy
'
);
addIssuableFormBlurSpy
=
jasmine
.
createSpy
(
'
spy
'
);
addIssuableFormSubmitSpy
=
jasmine
.
createSpy
(
'
spy
'
);
addIssuableFormCancelSpy
=
jasmine
.
createSpy
(
'
spy
'
);
eventHub
.
$on
(
'
addIssuableFormInput
'
,
addIssuableFormInputSpy
);
eventHub
.
$on
(
'
addIssuableFormBlur
'
,
addIssuableFormBlurSpy
);
eventHub
.
$on
(
'
addIssuableFormSubmit
'
,
addIssuableFormSubmitSpy
);
eventHub
.
$on
(
'
addIssuableFormCancel
'
,
addIssuableFormCancelSpy
);
const
el
=
document
.
createElement
(
'
div
'
);
// We need to append to body to get focus tests working
document
.
body
.
appendChild
(
el
);
vm
=
new
AddIssuableForm
({
propsData
:
{
inputValue
:
''
,
addButtonLabel
:
'
Add issuable
'
,
pendingIssuables
:
[
issuable1
,
],
},
}).
$mount
(
el
);
spyOn
(
vm
,
'
onInputWrapperClick
'
).
and
.
callThrough
();
});
afterEach
(()
=>
{
eventHub
.
$off
(
'
addIssuableFormInput
'
,
addIssuableFormInputSpy
);
eventHub
.
$off
(
'
addIssuableFormBlur
'
,
addIssuableFormBlurSpy
);
eventHub
.
$off
(
'
addIssuableFormSubmit
'
,
addIssuableFormSubmitSpy
);
eventHub
.
$off
(
'
addIssuableFormCancel
'
,
addIssuableFormCancelSpy
);
});
it
(
'
when clicking somewhere on the input wrapper should focus the input
'
,
()
=>
{
expect
(
vm
.
onInputWrapperClick
).
not
.
toHaveBeenCalled
();
vm
.
$refs
.
issuableFormWrapper
.
click
();
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$refs
.
issuableFormWrapper
.
classList
.
contains
(
'
focus
'
)).
toEqual
(
true
);
expect
(
vm
.
onInputWrapperClick
).
toHaveBeenCalled
();
expect
(
document
.
activeElement
).
toEqual
(
vm
.
$refs
.
input
);
});
});
it
(
'
when filling in the input
'
,
()
=>
{
expect
(
addIssuableFormInputSpy
).
not
.
toHaveBeenCalled
();
const
newInputValue
=
'
filling in things
'
;
vm
.
$refs
.
input
.
value
=
newInputValue
;
vm
.
onInput
();
expect
(
addIssuableFormInputSpy
).
toHaveBeenCalledWith
(
newInputValue
,
newInputValue
.
length
);
});
it
(
'
when blurring the input
'
,
()
=>
{
expect
(
addIssuableFormInputSpy
).
not
.
toHaveBeenCalled
();
const
newInputValue
=
'
filling in things
'
;
vm
.
$refs
.
input
.
value
=
newInputValue
;
vm
.
onBlur
();
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$refs
.
issuableFormWrapper
.
classList
.
contains
(
'
focus
'
)).
toEqual
(
false
);
expect
(
addIssuableFormBlurSpy
).
toHaveBeenCalledWith
(
newInputValue
);
});
});
it
(
'
when submitting pending issues
'
,
()
=>
{
expect
(
addIssuableFormSubmitSpy
).
not
.
toHaveBeenCalled
();
vm
.
onFormSubmit
();
expect
(
addIssuableFormSubmitSpy
).
toHaveBeenCalled
();
});
it
(
'
when canceling form to collapse
'
,
()
=>
{
expect
(
addIssuableFormCancelSpy
).
not
.
toHaveBeenCalled
();
vm
.
onFormCancel
();
expect
(
addIssuableFormCancelSpy
).
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