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
d51ecaaa
Commit
d51ecaaa
authored
Mar 12, 2021
by
Tom Quirk
Committed by
Phil Hughes
Mar 12, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add error/loading state to Jira Issues detail
Adds basic error and loading states.
parent
195d5f87
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
118 additions
and
57 deletions
+118
-57
ee/app/assets/javascripts/analytics/productivity_analytics/components/app.vue
...ripts/analytics/productivity_analytics/components/app.vue
+1
-1
ee/app/assets/javascripts/integrations/jira/issues_show/components/jira_issues_show_root.vue
...ons/jira/issues_show/components/jira_issues_show_root.vue
+81
-54
ee/spec/frontend/integrations/jira/issues_show/components/jira_issues_show_root_spec.js
...jira/issues_show/components/jira_issues_show_root_spec.js
+33
-2
locale/gitlab.pot
locale/gitlab.pot
+3
-0
No files found.
ee/app/assets/javascripts/analytics/productivity_analytics/components/app.vue
View file @
d51ecaaa
...
@@ -346,7 +346,7 @@ export default {
...
@@ -346,7 +346,7 @@ export default {
@
columnMetricChange=
"setColumnMetric"
@
columnMetricChange=
"setColumnMetric"
@
pageChange=
"setPage"
@
pageChange=
"setPage"
/>
/>
<gl-alert
v-if=
"showMergeRequestTableNoData"
variant=
"info"
:dismiss
a
ble=
"false"
>
<gl-alert
v-if=
"showMergeRequestTableNoData"
variant=
"info"
:dismiss
i
ble=
"false"
>
{{
__
(
'
There is no data available. Please change your selection.
'
)
}}
{{
__
(
'
There is no data available. Please change your selection.
'
)
}}
</gl-alert>
</gl-alert>
</div>
</div>
...
...
ee/app/assets/javascripts/integrations/jira/issues_show/components/jira_issues_show_root.vue
View file @
d51ecaaa
<
script
>
<
script
>
import
{
GlAlert
,
GlSprintf
,
GlLink
,
GlBadge
,
GlTooltipDirective
as
GlTooltip
}
from
'
@gitlab/ui
'
;
import
{
GlAlert
,
GlSprintf
,
GlLink
,
GlLoadingIcon
,
GlBadge
,
GlTooltipDirective
as
GlTooltip
,
}
from
'
@gitlab/ui
'
;
import
{
fetchIssue
}
from
'
ee/integrations/jira/issues_show/api
'
;
import
{
fetchIssue
}
from
'
ee/integrations/jira/issues_show/api
'
;
import
JiraIssueSidebar
from
'
ee/integrations/jira/issues_show/components/sidebar/jira_issues_sidebar_root.vue
'
;
import
JiraIssueSidebar
from
'
ee/integrations/jira/issues_show/components/sidebar/jira_issues_sidebar_root.vue
'
;
import
{
issueStates
,
issueStateLabels
}
from
'
ee/integrations/jira/issues_show/constants
'
;
import
{
issueStates
,
issueStateLabels
}
from
'
ee/integrations/jira/issues_show/constants
'
;
import
IssuableShow
from
'
~/issuable_show/components/issuable_show_root.vue
'
;
import
IssuableShow
from
'
~/issuable_show/components/issuable_show_root.vue
'
;
import
{
convertObjectPropsToCamelCase
}
from
'
~/lib/utils/common_utils
'
;
import
{
convertObjectPropsToCamelCase
}
from
'
~/lib/utils/common_utils
'
;
import
{
s__
}
from
'
~/locale
'
;
import
Note
from
'
./note.vue
'
;
import
Note
from
'
./note.vue
'
;
export
default
{
export
default
{
...
@@ -14,6 +22,7 @@ export default {
...
@@ -14,6 +22,7 @@ export default {
GlSprintf
,
GlSprintf
,
GlLink
,
GlLink
,
GlBadge
,
GlBadge
,
GlLoadingIcon
,
IssuableShow
,
IssuableShow
,
JiraIssueSidebar
,
JiraIssueSidebar
,
Note
,
Note
,
...
@@ -29,6 +38,7 @@ export default {
...
@@ -29,6 +38,7 @@ export default {
data
()
{
data
()
{
return
{
return
{
isLoading
:
true
,
isLoading
:
true
,
errorMessage
:
null
,
issue
:
{},
issue
:
{},
};
};
},
},
...
@@ -46,13 +56,25 @@ export default {
...
@@ -46,13 +56,25 @@ export default {
return
this
.
isIssueOpen
?
'
issue-open-m
'
:
'
mobile-issue-close
'
;
return
this
.
isIssueOpen
?
'
issue-open-m
'
:
'
mobile-issue-close
'
;
},
},
},
},
async
mounted
()
{
mounted
()
{
this
.
issue
=
convertObjectPropsToCamelCase
(
await
fetchIssue
(
this
.
issuesShowPath
),
{
this
.
loadIssue
();
deep
:
true
,
});
this
.
isLoading
=
false
;
},
},
methods
:
{
methods
:
{
loadIssue
()
{
fetchIssue
(
this
.
issuesShowPath
)
.
then
((
issue
)
=>
{
this
.
issue
=
convertObjectPropsToCamelCase
(
issue
,
{
deep
:
true
});
})
.
catch
(()
=>
{
this
.
errorMessage
=
s__
(
'
JiraService|Failed to load Jira issue. View the issue in Jira, or reload the page.
'
,
);
})
.
finally
(()
=>
{
this
.
isLoading
=
false
;
});
},
jiraIssueCommentId
(
id
)
{
jiraIssueCommentId
(
id
)
{
return
`jira_note_
${
id
}
`
;
return
`jira_note_
${
id
}
`
;
},
},
...
@@ -62,57 +84,62 @@ export default {
...
@@ -62,57 +84,62 @@ export default {
<
template
>
<
template
>
<div
class=
"gl-mt-5"
>
<div
class=
"gl-mt-5"
>
<gl-alert
<gl-loading-icon
v-if=
"isLoading"
size=
"lg"
/>
variant=
"info"
<gl-alert
v-else-if=
"errorMessage"
variant=
"danger"
:dismissible=
"false"
>
:dismissible=
"false"
{{
errorMessage
}}
:title=
"s__('JiraService|This issue is synchronized with Jira')"
class=
"gl-mb-2"
>
<gl-sprintf
:message=
"
s__(
`JiraService|Not all data may be displayed here. To view more details or make changes to this issue, go to %
{linkStart}Jira%{linkEnd}.`,
)
"
>
<template
#link
="
{ content }">
<gl-link
:href=
"issue.webUrl"
target=
"_blank"
>
{{
content
}}
</gl-link>
</
template
>
</gl-sprintf>
</gl-alert>
</gl-alert>
<template
v-else
>
<gl-alert
variant=
"info"
:dismissible=
"false"
:title=
"s__('JiraService|This issue is synchronized with Jira')"
class=
"gl-mb-2"
>
<gl-sprintf
:message=
"
s__(
`JiraService|Not all data may be displayed here. To view more details or make changes to this issue, go to %
{linkStart}Jira%{linkEnd}.`,
)
"
>
<template
#link
="
{ content }">
<gl-link
:href=
"issue.webUrl"
target=
"_blank"
>
{{
content
}}
</gl-link>
</
template
>
</gl-sprintf>
</gl-alert>
<issuable-show
<issuable-show
v-if=
"!isLoading"
:issuable=
"issue"
:issuable=
"issue"
:enable-edit=
"false"
:enable-edit=
"false"
:status-badge-class=
"statusBadgeClass"
:status-badge-class=
"statusBadgeClass"
:status-icon=
"statusIcon"
:status-icon=
"statusIcon"
>
>
<
template
#status-badge
>
{{
statusBadgeText
}}
</
template
>
<
template
#status-badge
>
{{
statusBadgeText
}}
</
template
>
<
template
#right-sidebar-items=
"{ sidebarExpanded }"
>
<
template
#right-sidebar-items=
"{ sidebarExpanded }"
>
<jira-issue-sidebar
:sidebar-expanded=
"sidebarExpanded"
:issue=
"issue"
/>
<jira-issue-sidebar
:sidebar-expanded=
"sidebarExpanded"
:issue=
"issue"
/>
</
template
>
</
template
>
<
template
#discussion
>
<
template
#discussion
>
<note
<note
v-for=
"comment in issue.comments"
v-for=
"comment in issue.comments"
:id=
"jiraIssueCommentId(comment.id)"
:id=
"jiraIssueCommentId(comment.id)"
:key=
"comment.id"
:key=
"comment.id"
:author-avatar-url=
"comment.author.avatarUrl"
:author-avatar-url=
"comment.author.avatarUrl"
:author-web-url=
"comment.author.webUrl"
:author-web-url=
"comment.author.webUrl"
:author-name=
"comment.author.name"
:author-name=
"comment.author.name"
:author-username=
"comment.author.username"
:author-username=
"comment.author.username"
:note-body-html=
"comment.bodyHtml"
:note-body-html=
"comment.bodyHtml"
:note-created-at=
"comment.createdAt"
:note-created-at=
"comment.createdAt"
>
>
<template
#badges
>
<template
#badges
>
<gl-badge
v-gl-tooltip=
"
{ title: __('This is a Jira user.') }">
<gl-badge
v-gl-tooltip=
"
{ title: __('This is a Jira user.') }">
{{
__
(
'
Jira user
'
)
}}
{{
__
(
'
Jira user
'
)
}}
</gl-badge>
</gl-badge>
</
template
>
</
template
>
</note>
</note>
</template>
</template>
</issuable-show>
</issuable-show>
</template>
</div>
</div>
</template>
</template>
ee/spec/frontend/integrations/jira/issues_show/components/jira_issues_show_root_spec.js
View file @
d51ecaaa
import
{
GlAlert
,
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
JiraIssuesShow
from
'
ee/integrations/jira/issues_show/components/jira_issues_show_root.vue
'
;
import
JiraIssuesShow
from
'
ee/integrations/jira/issues_show/components/jira_issues_show_root.vue
'
;
...
@@ -14,6 +15,8 @@ describe('JiraIssuesShow', () => {
...
@@ -14,6 +15,8 @@ describe('JiraIssuesShow', () => {
let
wrapper
;
let
wrapper
;
let
mockAxios
;
let
mockAxios
;
const
findGlAlert
=
()
=>
wrapper
.
findComponent
(
GlAlert
);
const
findGlLoadingIcon
=
()
=>
wrapper
.
findComponent
(
GlLoadingIcon
);
const
findIssuableShow
=
()
=>
wrapper
.
findComponent
(
IssuableShow
);
const
findIssuableShow
=
()
=>
wrapper
.
findComponent
(
IssuableShow
);
const
findIssuableShowStatusBadge
=
()
=>
const
findIssuableShowStatusBadge
=
()
=>
wrapper
.
findComponent
(
IssuableHeader
).
find
(
'
[data-testid="status"]
'
);
wrapper
.
findComponent
(
IssuableHeader
).
find
(
'
[data-testid="status"]
'
);
...
@@ -43,13 +46,42 @@ describe('JiraIssuesShow', () => {
...
@@ -43,13 +46,42 @@ describe('JiraIssuesShow', () => {
}
}
});
});
describe
(
'
when issue is loading
'
,
()
=>
{
it
(
'
renders GlLoadingIcon
'
,
()
=>
{
createComponent
();
expect
(
findGlLoadingIcon
().
exists
()).
toBe
(
true
);
expect
(
findGlAlert
().
exists
()).
toBe
(
false
);
expect
(
findIssuableShow
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
when error occurs during fetch
'
,
()
=>
{
it
(
'
renders error message
'
,
async
()
=>
{
mockAxios
.
onGet
(
mockJiraIssuesShowPath
).
replyOnce
(
500
);
createComponent
();
await
waitForPromises
();
const
alert
=
findGlAlert
();
expect
(
findGlLoadingIcon
().
exists
()).
toBe
(
false
);
expect
(
alert
.
exists
()).
toBe
(
true
);
expect
(
alert
.
text
()).
toBe
(
'
Failed to load Jira issue. View the issue in Jira, or reload the page.
'
,
);
expect
(
alert
.
props
(
'
variant
'
)).
toBe
(
'
danger
'
);
expect
(
findIssuableShow
().
exists
()).
toBe
(
false
);
});
});
it
(
'
renders IssuableShow
'
,
async
()
=>
{
it
(
'
renders IssuableShow
'
,
async
()
=>
{
mockAxios
.
onGet
(
mockJiraIssuesShowPath
).
replyOnce
(
200
,
mockJiraIssue
);
mockAxios
.
onGet
(
mockJiraIssuesShowPath
).
replyOnce
(
200
,
mockJiraIssue
);
createComponent
();
createComponent
();
await
waitForPromises
();
await
waitForPromises
();
await
wrapper
.
vm
.
$nextTick
();
expect
(
findGlLoadingIcon
().
exists
()).
toBe
(
false
);
expect
(
findIssuableShow
().
exists
()).
toBe
(
true
);
expect
(
findIssuableShow
().
exists
()).
toBe
(
true
);
});
});
...
@@ -63,7 +95,6 @@ describe('JiraIssuesShow', () => {
...
@@ -63,7 +95,6 @@ describe('JiraIssuesShow', () => {
createComponent
();
createComponent
();
await
waitForPromises
();
await
waitForPromises
();
await
wrapper
.
vm
.
$nextTick
();
});
});
it
(
'
sets `statusIcon` prop correctly
'
,
()
=>
{
it
(
'
sets `statusIcon` prop correctly
'
,
()
=>
{
...
...
locale/gitlab.pot
View file @
d51ecaaa
...
@@ -17229,6 +17229,9 @@ msgstr ""
...
@@ -17229,6 +17229,9 @@ msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
msgid "JiraService|Events for %{noteable_model_name} are disabled."
msgstr ""
msgstr ""
msgid "JiraService|Failed to load Jira issue. View the issue in Jira, or reload the page."
msgstr ""
msgid "JiraService|Fetch issue types for this Jira project"
msgid "JiraService|Fetch issue types for this Jira project"
msgstr ""
msgstr ""
...
...
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