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
4410a1fa
Commit
4410a1fa
authored
Mar 28, 2018
by
Tim Zallmann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Patch applied for Open MR in IDE
parent
4cb37a20
Changes
41
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
41 changed files
with
1396 additions
and
582 deletions
+1396
-582
app/assets/javascripts/api.js
app/assets/javascripts/api.js
+88
-58
app/assets/javascripts/ide/components/changed_file_icon.vue
app/assets/javascripts/ide/components/changed_file_icon.vue
+17
-17
app/assets/javascripts/ide/components/editor_mode_dropdown.vue
...ssets/javascripts/ide/components/editor_mode_dropdown.vue
+63
-24
app/assets/javascripts/ide/components/ide.vue
app/assets/javascripts/ide/components/ide.vue
+43
-42
app/assets/javascripts/ide/components/mr_file_icon.vue
app/assets/javascripts/ide/components/mr_file_icon.vue
+29
-0
app/assets/javascripts/ide/components/repo_editor.vue
app/assets/javascripts/ide/components/repo_editor.vue
+17
-12
app/assets/javascripts/ide/components/repo_file.vue
app/assets/javascripts/ide/components/repo_file.vue
+13
-9
app/assets/javascripts/ide/components/repo_file_status_icon.vue
...sets/javascripts/ide/components/repo_file_status_icon.vue
+20
-20
app/assets/javascripts/ide/components/repo_tabs.vue
app/assets/javascripts/ide/components/repo_tabs.vue
+38
-33
app/assets/javascripts/ide/ide_router.js
app/assets/javascripts/ide/ide_router.js
+56
-4
app/assets/javascripts/ide/lib/common/model.js
app/assets/javascripts/ide/lib/common/model.js
+16
-12
app/assets/javascripts/ide/lib/editor.js
app/assets/javascripts/ide/lib/editor.js
+13
-7
app/assets/javascripts/ide/services/index.js
app/assets/javascripts/ide/services/index.js
+24
-1
app/assets/javascripts/ide/stores/actions.js
app/assets/javascripts/ide/stores/actions.js
+4
-7
app/assets/javascripts/ide/stores/actions/file.js
app/assets/javascripts/ide/stores/actions/file.js
+40
-33
app/assets/javascripts/ide/stores/actions/merge_request.js
app/assets/javascripts/ide/stores/actions/merge_request.js
+84
-0
app/assets/javascripts/ide/stores/actions/tree.js
app/assets/javascripts/ide/stores/actions/tree.js
+50
-48
app/assets/javascripts/ide/stores/getters.js
app/assets/javascripts/ide/stores/getters.js
+11
-4
app/assets/javascripts/ide/stores/mutation_types.js
app/assets/javascripts/ide/stores/mutation_types.js
+8
-0
app/assets/javascripts/ide/stores/mutations.js
app/assets/javascripts/ide/stores/mutations.js
+4
-7
app/assets/javascripts/ide/stores/mutations/file.js
app/assets/javascripts/ide/stores/mutations/file.js
+12
-0
app/assets/javascripts/ide/stores/mutations/merge_request.js
app/assets/javascripts/ide/stores/mutations/merge_request.js
+33
-0
app/assets/javascripts/ide/stores/mutations/project.js
app/assets/javascripts/ide/stores/mutations/project.js
+1
-0
app/assets/javascripts/ide/stores/state.js
app/assets/javascripts/ide/stores/state.js
+1
-0
app/assets/javascripts/ide/stores/utils.js
app/assets/javascripts/ide/stores/utils.js
+12
-10
app/assets/javascripts/lib/utils/url_utility.js
app/assets/javascripts/lib/utils/url_utility.js
+9
-1
app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
.../vue_merge_request_widget/components/mr_widget_header.vue
+54
-43
app/assets/stylesheets/pages/repo.scss
app/assets/stylesheets/pages/repo.scss
+2
-3
spec/javascripts/api_spec.js
spec/javascripts/api_spec.js
+138
-59
spec/javascripts/ide/components/changed_file_icon_spec.js
spec/javascripts/ide/components/changed_file_icon_spec.js
+2
-1
spec/javascripts/ide/components/repo_editor_spec.js
spec/javascripts/ide/components/repo_editor_spec.js
+58
-0
spec/javascripts/ide/components/repo_tabs_spec.js
spec/javascripts/ide/components/repo_tabs_spec.js
+2
-0
spec/javascripts/ide/lib/common/model_spec.js
spec/javascripts/ide/lib/common/model_spec.js
+12
-2
spec/javascripts/ide/lib/editor_spec.js
spec/javascripts/ide/lib/editor_spec.js
+25
-0
spec/javascripts/ide/stores/actions/file_spec.js
spec/javascripts/ide/stores/actions/file_spec.js
+35
-8
spec/javascripts/ide/stores/actions/merge_request_spec.js
spec/javascripts/ide/stores/actions/merge_request_spec.js
+110
-0
spec/javascripts/ide/stores/actions/tree_spec.js
spec/javascripts/ide/stores/actions/tree_spec.js
+3
-9
spec/javascripts/ide/stores/getters_spec.js
spec/javascripts/ide/stores/getters_spec.js
+21
-1
spec/javascripts/ide/stores/mutations/file_spec.js
spec/javascripts/ide/stores/mutations/file_spec.js
+25
-1
spec/javascripts/ide/stores/mutations/merge_request_spec.js
spec/javascripts/ide/stores/mutations/merge_request_spec.js
+65
-0
spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js
...scripts/vue_mr_widget/components/mr_widget_header_spec.js
+138
-106
No files found.
app/assets/javascripts/api.js
View file @
4410a1fa
...
@@ -10,6 +10,9 @@ const Api = {
...
@@ -10,6 +10,9 @@ const Api = {
projectsPath
:
'
/api/:version/projects.json
'
,
projectsPath
:
'
/api/:version/projects.json
'
,
projectPath
:
'
/api/:version/projects/:id
'
,
projectPath
:
'
/api/:version/projects/:id
'
,
projectLabelsPath
:
'
/:namespace_path/:project_path/labels
'
,
projectLabelsPath
:
'
/:namespace_path/:project_path/labels
'
,
mergeRequestPath
:
'
/api/:version/projects/:id/merge_requests/:mrid
'
,
mergeRequestChangesPath
:
'
/api/:version/projects/:id/merge_requests/:mrid/changes
'
,
mergeRequestVersionsPath
:
'
/api/:version/projects/:id/merge_requests/:mrid/versions
'
,
groupLabelsPath
:
'
/groups/:namespace_path/-/labels
'
,
groupLabelsPath
:
'
/groups/:namespace_path/-/labels
'
,
licensePath
:
'
/api/:version/templates/licenses/:key
'
,
licensePath
:
'
/api/:version/templates/licenses/:key
'
,
gitignorePath
:
'
/api/:version/templates/gitignores/:key
'
,
gitignorePath
:
'
/api/:version/templates/gitignores/:key
'
,
...
@@ -24,25 +27,27 @@ const Api = {
...
@@ -24,25 +27,27 @@ const Api = {
geoNodesPath
:
'
/api/:version/geo_nodes
'
,
geoNodesPath
:
'
/api/:version/geo_nodes
'
,
group
(
groupId
,
callback
)
{
group
(
groupId
,
callback
)
{
const
url
=
Api
.
buildUrl
(
Api
.
groupPath
)
const
url
=
Api
.
buildUrl
(
Api
.
groupPath
).
replace
(
'
:id
'
,
groupId
);
.
replace
(
'
:id
'
,
groupId
);
return
axios
.
get
(
url
).
then
(({
data
})
=>
{
return
axios
.
get
(
url
)
callback
(
data
);
.
then
(({
data
})
=>
{
callback
(
data
);
return
data
;
return
data
;
});
});
},
},
// Return groups list. Filtered by query
// Return groups list. Filtered by query
groups
(
query
,
options
,
callback
=
$
.
noop
)
{
groups
(
query
,
options
,
callback
=
$
.
noop
)
{
const
url
=
Api
.
buildUrl
(
Api
.
groupsPath
);
const
url
=
Api
.
buildUrl
(
Api
.
groupsPath
);
return
axios
.
get
(
url
,
{
return
axios
params
:
Object
.
assign
({
.
get
(
url
,
{
search
:
query
,
params
:
Object
.
assign
(
per_page
:
20
,
{
},
options
),
search
:
query
,
})
per_page
:
20
,
},
options
,
),
})
.
then
(({
data
})
=>
{
.
then
(({
data
})
=>
{
callback
(
data
);
callback
(
data
);
...
@@ -53,12 +58,13 @@ const Api = {
...
@@ -53,12 +58,13 @@ const Api = {
// Return namespaces list. Filtered by query
// Return namespaces list. Filtered by query
namespaces
(
query
,
callback
)
{
namespaces
(
query
,
callback
)
{
const
url
=
Api
.
buildUrl
(
Api
.
namespacesPath
);
const
url
=
Api
.
buildUrl
(
Api
.
namespacesPath
);
return
axios
.
get
(
url
,
{
return
axios
params
:
{
.
get
(
url
,
{
search
:
query
,
params
:
{
per_page
:
20
,
search
:
query
,
},
per_page
:
20
,
})
},
})
.
then
(({
data
})
=>
callback
(
data
));
.
then
(({
data
})
=>
callback
(
data
));
},
},
...
@@ -75,9 +81,10 @@ const Api = {
...
@@ -75,9 +81,10 @@ const Api = {
defaults
.
membership
=
true
;
defaults
.
membership
=
true
;
}
}
return
axios
.
get
(
url
,
{
return
axios
params
:
Object
.
assign
(
defaults
,
options
),
.
get
(
url
,
{
})
params
:
Object
.
assign
(
defaults
,
options
),
})
.
then
(({
data
})
=>
{
.
then
(({
data
})
=>
{
callback
(
data
);
callback
(
data
);
...
@@ -87,8 +94,32 @@ const Api = {
...
@@ -87,8 +94,32 @@ const Api = {
// Return single project
// Return single project
project
(
projectPath
)
{
project
(
projectPath
)
{
const
url
=
Api
.
buildUrl
(
Api
.
projectPath
)
const
url
=
Api
.
buildUrl
(
Api
.
projectPath
).
replace
(
'
:id
'
,
encodeURIComponent
(
projectPath
));
.
replace
(
'
:id
'
,
encodeURIComponent
(
projectPath
));
return
axios
.
get
(
url
);
},
// Return Merge Request for project
mergeRequest
(
projectPath
,
mergeRequestId
)
{
const
url
=
Api
.
buildUrl
(
Api
.
mergeRequestPath
)
.
replace
(
'
:id
'
,
encodeURIComponent
(
projectPath
))
.
replace
(
'
:mrid
'
,
mergeRequestId
);
return
axios
.
get
(
url
);
},
mergeRequestChanges
(
projectPath
,
mergeRequestId
)
{
const
url
=
Api
.
buildUrl
(
Api
.
mergeRequestChangesPath
)
.
replace
(
'
:id
'
,
encodeURIComponent
(
projectPath
))
.
replace
(
'
:mrid
'
,
mergeRequestId
);
return
axios
.
get
(
url
);
},
mergeRequestVersions
(
projectPath
,
mergeRequestId
)
{
const
url
=
Api
.
buildUrl
(
Api
.
mergeRequestVersionsPath
)
.
replace
(
'
:id
'
,
encodeURIComponent
(
projectPath
))
.
replace
(
'
:mrid
'
,
mergeRequestId
);
return
axios
.
get
(
url
);
return
axios
.
get
(
url
);
},
},
...
@@ -104,30 +135,30 @@ const Api = {
...
@@ -104,30 +135,30 @@ const Api = {
url
=
Api
.
buildUrl
(
Api
.
groupLabelsPath
).
replace
(
'
:namespace_path
'
,
namespacePath
);
url
=
Api
.
buildUrl
(
Api
.
groupLabelsPath
).
replace
(
'
:namespace_path
'
,
namespacePath
);
}
}
return
axios
.
post
(
url
,
{
return
axios
label
:
data
,
.
post
(
url
,
{
})
label
:
data
,
})
.
then
(
res
=>
callback
(
res
.
data
))
.
then
(
res
=>
callback
(
res
.
data
))
.
catch
(
e
=>
callback
(
e
.
response
.
data
));
.
catch
(
e
=>
callback
(
e
.
response
.
data
));
},
},
// Return group projects list. Filtered by query
// Return group projects list. Filtered by query
groupProjects
(
groupId
,
query
,
callback
)
{
groupProjects
(
groupId
,
query
,
callback
)
{
const
url
=
Api
.
buildUrl
(
Api
.
groupProjectsPath
)
const
url
=
Api
.
buildUrl
(
Api
.
groupProjectsPath
)
.
replace
(
'
:id
'
,
groupId
);
.
replace
(
'
:id
'
,
groupId
);
return
axios
return
axios
.
get
(
url
,
{
.
get
(
url
,
{
params
:
{
params
:
{
search
:
query
,
search
:
query
,
per_page
:
20
,
per_page
:
20
,
},
},
})
})
.
then
(({
data
})
=>
callback
(
data
));
.
then
(({
data
})
=>
callback
(
data
));
},
},
commitMultiple
(
id
,
data
)
{
commitMultiple
(
id
,
data
)
{
// see https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
// see https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
const
url
=
Api
.
buildUrl
(
Api
.
commitPath
)
const
url
=
Api
.
buildUrl
(
Api
.
commitPath
).
replace
(
'
:id
'
,
encodeURIComponent
(
id
));
.
replace
(
'
:id
'
,
encodeURIComponent
(
id
));
return
axios
.
post
(
url
,
JSON
.
stringify
(
data
),
{
return
axios
.
post
(
url
,
JSON
.
stringify
(
data
),
{
headers
:
{
headers
:
{
'
Content-Type
'
:
'
application/json; charset=utf-8
'
,
'
Content-Type
'
:
'
application/json; charset=utf-8
'
,
...
@@ -138,39 +169,34 @@ const Api = {
...
@@ -138,39 +169,34 @@ const Api = {
branchSingle
(
id
,
branch
)
{
branchSingle
(
id
,
branch
)
{
const
url
=
Api
.
buildUrl
(
Api
.
branchSinglePath
)
const
url
=
Api
.
buildUrl
(
Api
.
branchSinglePath
)
.
replace
(
'
:id
'
,
encodeURIComponent
(
id
))
.
replace
(
'
:id
'
,
encodeURIComponent
(
id
))
.
replace
(
'
:branch
'
,
branch
);
.
replace
(
'
:branch
'
,
encodeURIComponent
(
branch
)
);
return
axios
.
get
(
url
);
return
axios
.
get
(
url
);
},
},
// Return text for a specific license
// Return text for a specific license
licenseText
(
key
,
data
,
callback
)
{
licenseText
(
key
,
data
,
callback
)
{
const
url
=
Api
.
buildUrl
(
Api
.
licensePath
)
const
url
=
Api
.
buildUrl
(
Api
.
licensePath
)
.
replace
(
'
:key
'
,
key
);
.
replace
(
'
:key
'
,
key
);
return
axios
return
axios
.
get
(
url
,
{
.
get
(
url
,
{
params
:
data
,
params
:
data
,
})
})
.
then
(
res
=>
callback
(
res
.
data
));
.
then
(
res
=>
callback
(
res
.
data
));
},
},
gitignoreText
(
key
,
callback
)
{
gitignoreText
(
key
,
callback
)
{
const
url
=
Api
.
buildUrl
(
Api
.
gitignorePath
)
const
url
=
Api
.
buildUrl
(
Api
.
gitignorePath
).
replace
(
'
:key
'
,
key
);
.
replace
(
'
:key
'
,
key
);
return
axios
.
get
(
url
).
then
(({
data
})
=>
callback
(
data
));
return
axios
.
get
(
url
)
.
then
(({
data
})
=>
callback
(
data
));
},
},
gitlabCiYml
(
key
,
callback
)
{
gitlabCiYml
(
key
,
callback
)
{
const
url
=
Api
.
buildUrl
(
Api
.
gitlabCiYmlPath
)
const
url
=
Api
.
buildUrl
(
Api
.
gitlabCiYmlPath
).
replace
(
'
:key
'
,
key
);
.
replace
(
'
:key
'
,
key
);
return
axios
.
get
(
url
).
then
(({
data
})
=>
callback
(
data
));
return
axios
.
get
(
url
)
.
then
(({
data
})
=>
callback
(
data
));
},
},
dockerfileYml
(
key
,
callback
)
{
dockerfileYml
(
key
,
callback
)
{
const
url
=
Api
.
buildUrl
(
Api
.
dockerfilePath
).
replace
(
'
:key
'
,
key
);
const
url
=
Api
.
buildUrl
(
Api
.
dockerfilePath
).
replace
(
'
:key
'
,
key
);
return
axios
.
get
(
url
)
return
axios
.
get
(
url
).
then
(({
data
})
=>
callback
(
data
));
.
then
(({
data
})
=>
callback
(
data
));
},
},
issueTemplate
(
namespacePath
,
projectPath
,
key
,
type
,
callback
)
{
issueTemplate
(
namespacePath
,
projectPath
,
key
,
type
,
callback
)
{
...
@@ -179,7 +205,8 @@ const Api = {
...
@@ -179,7 +205,8 @@ const Api = {
.
replace
(
'
:type
'
,
type
)
.
replace
(
'
:type
'
,
type
)
.
replace
(
'
:project_path
'
,
projectPath
)
.
replace
(
'
:project_path
'
,
projectPath
)
.
replace
(
'
:namespace_path
'
,
namespacePath
);
.
replace
(
'
:namespace_path
'
,
namespacePath
);
return
axios
.
get
(
url
)
return
axios
.
get
(
url
)
.
then
(({
data
})
=>
callback
(
null
,
data
))
.
then
(({
data
})
=>
callback
(
null
,
data
))
.
catch
(
callback
);
.
catch
(
callback
);
},
},
...
@@ -187,10 +214,13 @@ const Api = {
...
@@ -187,10 +214,13 @@ const Api = {
users
(
query
,
options
)
{
users
(
query
,
options
)
{
const
url
=
Api
.
buildUrl
(
this
.
usersPath
);
const
url
=
Api
.
buildUrl
(
this
.
usersPath
);
return
axios
.
get
(
url
,
{
return
axios
.
get
(
url
,
{
params
:
Object
.
assign
({
params
:
Object
.
assign
(
search
:
query
,
{
per_page
:
20
,
search
:
query
,
},
options
),
per_page
:
20
,
},
options
,
),
});
});
},
},
...
...
app/assets/javascripts/ide/components/changed_file_icon.vue
View file @
4410a1fa
<
script
>
<
script
>
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
export
default
{
export
default
{
components
:
{
components
:
{
icon
,
icon
,
},
props
:
{
file
:
{
type
:
Object
,
required
:
true
,
},
},
props
:
{
},
file
:
{
computed
:
{
type
:
Object
,
changedIcon
()
{
required
:
true
,
return
this
.
file
.
tempFile
?
'
file-addition
'
:
'
file-modified
'
;
},
},
},
computed
:
{
changedIconClass
()
{
changedIcon
()
{
return
`multi-
${
this
.
changedIcon
}
`
;
return
this
.
file
.
tempFile
?
'
file-addition
'
:
'
file-modified
'
;
},
changedIconClass
()
{
return
`multi-
${
this
.
changedIcon
}
`
;
},
},
},
};
},
};
</
script
>
</
script
>
<
template
>
<
template
>
...
...
app/assets/javascripts/ide/components/editor_mode_dropdown.vue
View file @
4410a1fa
<
script
>
<
script
>
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
{
__
,
sprintf
}
from
'
~/locale
'
;
export
default
{
export
default
{
components
:
{
components
:
{
Icon
,
Icon
,
},
props
:
{
hasChanges
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
props
:
{
mergeRequestId
:
{
hasChanges
:
{
type
:
String
,
type
:
Boolean
,
required
:
false
,
required
:
false
,
default
:
''
,
default
:
false
,
},
viewer
:
{
type
:
String
,
required
:
true
,
},
showShadow
:
{
type
:
Boolean
,
required
:
true
,
},
},
},
methods
:
{
viewer
:
{
changeMode
(
mode
)
{
type
:
String
,
this
.
$emit
(
'
click
'
,
mode
);
required
:
true
,
},
},
},
};
showShadow
:
{
type
:
Boolean
,
required
:
true
,
},
},
computed
:
{
mergeReviewLine
()
{
return
sprintf
(
__
(
'
Reviewing (merge request !%{mergeRequestId})
'
),
{
mergeRequestId
:
this
.
mergeRequestId
,
});
},
},
methods
:
{
changeMode
(
mode
)
{
this
.
$emit
(
'
click
'
,
mode
);
},
},
};
</
script
>
</
script
>
<
template
>
<
template
>
...
@@ -43,7 +56,10 @@
...
@@ -43,7 +56,10 @@
}"
}"
data-toggle="dropdown"
data-toggle="dropdown"
>
>
<template
v-if=
"viewer === 'editor'"
>
<template
v-if=
"viewer === 'mrdiff' && mergeRequestId"
>
{{
mergeReviewLine
}}
</
template
>
<
template
v-else-if=
"viewer === 'editor'"
>
{{
__
(
'
Editing
'
)
}}
{{
__
(
'
Editing
'
)
}}
</
template
>
</
template
>
<
template
v-else
>
<
template
v-else
>
...
@@ -57,6 +73,29 @@
...
@@ -57,6 +73,29 @@
</button>
</button>
<div
class=
"dropdown-menu dropdown-menu-selectable dropdown-open-left"
>
<div
class=
"dropdown-menu dropdown-menu-selectable dropdown-open-left"
>
<ul>
<ul>
<
template
v-if=
"mergeRequestId"
>
<li>
<a
href=
"#"
@
click.prevent=
"changeMode('mrdiff')"
:class=
"
{
'is-active': viewer === 'mrdiff',
}"
>
<strong
class=
"dropdown-menu-inner-title"
>
{{
mergeReviewLine
}}
</strong>
<span
class=
"dropdown-menu-inner-content"
>
{{
__
(
'
Compare changes with the merge request target branch
'
)
}}
</span>
</a>
</li>
<li
role=
"separator"
class=
"divider"
>
</li>
</
template
>
<li>
<li>
<a
<a
href=
"#"
href=
"#"
...
...
app/assets/javascripts/ide/components/ide.vue
View file @
4410a1fa
<
script
>
<
script
>
import
{
mapState
,
mapGetters
}
from
'
vuex
'
;
import
{
mapState
,
mapGetters
}
from
'
vuex
'
;
import
ideSidebar
from
'
./ide_side_bar.vue
'
;
import
ideSidebar
from
'
./ide_side_bar.vue
'
;
import
ideContextbar
from
'
./ide_context_bar.vue
'
;
import
ideContextbar
from
'
./ide_context_bar.vue
'
;
import
repoTabs
from
'
./repo_tabs.vue
'
;
import
repoTabs
from
'
./repo_tabs.vue
'
;
import
repoFileButtons
from
'
./repo_file_buttons.vue
'
;
import
repoFileButtons
from
'
./repo_file_buttons.vue
'
;
import
ideStatusBar
from
'
./ide_status_bar.vue
'
;
import
ideStatusBar
from
'
./ide_status_bar.vue
'
;
import
repoEditor
from
'
./repo_editor.vue
'
;
import
repoEditor
from
'
./repo_editor.vue
'
;
export
default
{
export
default
{
components
:
{
components
:
{
ideSidebar
,
ideSidebar
,
ideContextbar
,
ideContextbar
,
repoTabs
,
repoTabs
,
repoFileButtons
,
repoFileButtons
,
ideStatusBar
,
ideStatusBar
,
repoEditor
,
repoEditor
,
},
props
:
{
emptyStateSvgPath
:
{
type
:
String
,
required
:
true
,
},
},
props
:
{
noChangesStateSvgPath
:
{
emptyStateSvgPath
:
{
type
:
String
,
type
:
String
,
required
:
true
,
required
:
true
,
},
noChangesStateSvgPath
:
{
type
:
String
,
required
:
true
,
},
committedStateSvgPath
:
{
type
:
String
,
required
:
true
,
},
},
},
com
puted
:
{
com
mittedStateSvgPath
:
{
...
mapState
([
'
changedFiles
'
,
'
openFiles
'
,
'
viewer
'
])
,
type
:
String
,
...
mapGetters
([
'
activeFile
'
,
'
hasChanges
'
])
,
required
:
true
,
},
},
mounted
()
{
},
const
returnValue
=
'
Are you sure you want to lose unsaved changes?
'
;
computed
:
{
window
.
onbeforeunload
=
e
=>
{
...
mapState
([
'
changedFiles
'
,
'
openFiles
'
,
'
viewer
'
,
'
currentMergeRequestId
'
]),
if
(
!
this
.
changedFiles
.
length
)
return
undefined
;
...
mapGetters
([
'
activeFile
'
,
'
hasChanges
'
]),
},
mounted
()
{
const
returnValue
=
'
Are you sure you want to lose unsaved changes?
'
;
window
.
onbeforeunload
=
e
=>
{
if
(
!
this
.
changedFiles
.
length
)
return
undefined
;
Object
.
assign
(
e
,
{
Object
.
assign
(
e
,
{
returnValue
,
returnValue
,
});
});
return
returnValue
;
return
returnValue
;
};
};
},
},
};
};
</
script
>
</
script
>
<
template
>
<
template
>
...
@@ -63,6 +63,7 @@
...
@@ -63,6 +63,7 @@
:files=
"openFiles"
:files=
"openFiles"
:viewer=
"viewer"
:viewer=
"viewer"
:has-changes=
"hasChanges"
:has-changes=
"hasChanges"
:merge-request-id=
"currentMergeRequestId"
/>
/>
<repo-editor
<repo-editor
class=
"multi-file-edit-pane-content"
class=
"multi-file-edit-pane-content"
...
...
app/assets/javascripts/ide/components/mr_file_icon.vue
0 → 100644
View file @
4410a1fa
<
script
>
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
tooltip
from
'
~/vue_shared/directives/tooltip
'
;
export
default
{
components
:
{
icon
,
},
directives
:
{
tooltip
,
},
props
:
{
file
:
{
type
:
Object
,
required
:
true
,
},
},
};
</
script
>
<
template
>
<icon
name=
"git-merge"
v-tooltip
title=
"Part of merge request changes"
css-classes=
"ide-file-changed-icon"
:size=
"12"
/>
</
template
>
app/assets/javascripts/ide/components/repo_editor.vue
View file @
4410a1fa
<
script
>
<
script
>
/* global monaco */
/* global monaco */
import
{
mapState
,
mapActions
}
from
'
vuex
'
;
import
{
mapState
,
map
Getters
,
map
Actions
}
from
'
vuex
'
;
import
flash
from
'
~/flash
'
;
import
flash
from
'
~/flash
'
;
import
monacoLoader
from
'
../monaco_loader
'
;
import
monacoLoader
from
'
../monaco_loader
'
;
import
Editor
from
'
../lib/editor
'
;
import
Editor
from
'
../lib/editor
'
;
...
@@ -13,12 +13,8 @@ export default {
...
@@ -13,12 +13,8 @@ export default {
},
},
},
},
computed
:
{
computed
:
{
...
mapState
([
...
mapState
([
'
leftPanelCollapsed
'
,
'
rightPanelCollapsed
'
,
'
viewer
'
,
'
delayViewerUpdated
'
]),
'
leftPanelCollapsed
'
,
...
mapGetters
([
'
currentMergeRequest
'
]),
'
rightPanelCollapsed
'
,
'
viewer
'
,
'
delayViewerUpdated
'
,
]),
shouldHideEditor
()
{
shouldHideEditor
()
{
return
this
.
file
&&
this
.
file
.
binary
&&
!
this
.
file
.
raw
;
return
this
.
file
&&
this
.
file
.
binary
&&
!
this
.
file
.
raw
;
},
},
...
@@ -68,9 +64,14 @@ export default {
...
@@ -68,9 +64,14 @@ export default {
this
.
editor
.
clearEditor
();
this
.
editor
.
clearEditor
();
this
.
getRawFileData
(
this
.
file
)
this
.
getRawFileData
({
path
:
this
.
file
.
path
,
baseSha
:
this
.
currentMergeRequest
?
this
.
currentMergeRequest
.
baseCommitSha
:
''
,
})
.
then
(()
=>
{
.
then
(()
=>
{
const
viewerPromise
=
this
.
delayViewerUpdated
?
this
.
updateViewer
(
'
editor
'
)
:
Promise
.
resolve
();
const
viewerPromise
=
this
.
delayViewerUpdated
?
this
.
updateViewer
(
'
editor
'
)
:
Promise
.
resolve
();
return
viewerPromise
;
return
viewerPromise
;
})
})
...
@@ -78,7 +79,7 @@ export default {
...
@@ -78,7 +79,7 @@ export default {
this
.
updateDelayViewerUpdated
(
false
);
this
.
updateDelayViewerUpdated
(
false
);
this
.
createEditorInstance
();
this
.
createEditorInstance
();
})
})
.
catch
(
(
err
)
=>
{
.
catch
(
err
=>
{
flash
(
'
Error setting up monaco. Please try again.
'
,
'
alert
'
,
document
,
null
,
false
,
true
);
flash
(
'
Error setting up monaco. Please try again.
'
,
'
alert
'
,
document
,
null
,
false
,
true
);
throw
err
;
throw
err
;
});
});
...
@@ -101,9 +102,13 @@ export default {
...
@@ -101,9 +102,13 @@ export default {
this
.
model
=
this
.
editor
.
createModel
(
this
.
file
);
this
.
model
=
this
.
editor
.
createModel
(
this
.
file
);
this
.
editor
.
attachModel
(
this
.
model
);
if
(
this
.
viewer
===
'
mrdiff
'
)
{
this
.
editor
.
attachMergeRequestModel
(
this
.
model
);
}
else
{
this
.
editor
.
attachModel
(
this
.
model
);
}
this
.
model
.
onChange
(
(
model
)
=>
{
this
.
model
.
onChange
(
model
=>
{
const
{
file
}
=
model
;
const
{
file
}
=
model
;
if
(
file
.
active
)
{
if
(
file
.
active
)
{
...
...
app/assets/javascripts/ide/components/repo_file.vue
View file @
4410a1fa
...
@@ -6,6 +6,7 @@ import router from '../ide_router';
...
@@ -6,6 +6,7 @@ import router from '../ide_router';
import
newDropdown
from
'
./new_dropdown/index.vue
'
;
import
newDropdown
from
'
./new_dropdown/index.vue
'
;
import
fileStatusIcon
from
'
./repo_file_status_icon.vue
'
;
import
fileStatusIcon
from
'
./repo_file_status_icon.vue
'
;
import
changedFileIcon
from
'
./changed_file_icon.vue
'
;
import
changedFileIcon
from
'
./changed_file_icon.vue
'
;
import
mrFileIcon
from
'
./mr_file_icon.vue
'
;
export
default
{
export
default
{
name
:
'
RepoFile
'
,
name
:
'
RepoFile
'
,
...
@@ -15,6 +16,7 @@ export default {
...
@@ -15,6 +16,7 @@ export default {
fileStatusIcon
,
fileStatusIcon
,
fileIcon
,
fileIcon
,
changedFileIcon
,
changedFileIcon
,
mrFileIcon
,
},
},
props
:
{
props
:
{
file
:
{
file
:
{
...
@@ -56,10 +58,7 @@ export default {
...
@@ -56,10 +58,7 @@ export default {
...
mapActions
([
'
toggleTreeOpen
'
,
'
updateDelayViewerUpdated
'
]),
...
mapActions
([
'
toggleTreeOpen
'
,
'
updateDelayViewerUpdated
'
]),
clickFile
()
{
clickFile
()
{
// Manual Action if a tree is selected/opened
// Manual Action if a tree is selected/opened
if
(
if
(
this
.
isTree
&&
this
.
$router
.
currentRoute
.
path
===
`/project
${
this
.
file
.
url
}
`
)
{
this
.
isTree
&&
this
.
$router
.
currentRoute
.
path
===
`/project
${
this
.
file
.
url
}
`
)
{
this
.
toggleTreeOpen
(
this
.
file
.
path
);
this
.
toggleTreeOpen
(
this
.
file
.
path
);
}
}
...
@@ -102,11 +101,16 @@ export default {
...
@@ -102,11 +101,16 @@ export default {
:file=
"file"
:file=
"file"
/>
/>
</span>
</span>
<changed-file-icon
<span
class=
"pull-right"
>
:file=
"file"
<mr-file-icon
v-if=
"file.changed || file.tempFile"
:file=
"file"
class=
"prepend-top-5 pull-right"
v-if=
"file.mrChange"
/>
/>
<changed-file-icon
:file=
"file"
v-if=
"file.changed || file.tempFile"
/>
</span>
<new-dropdown
<new-dropdown
v-if=
"isTree"
v-if=
"isTree"
:project-id=
"file.projectId"
:project-id=
"file.projectId"
...
...
app/assets/javascripts/ide/components/repo_file_status_icon.vue
View file @
4410a1fa
<
script
>
<
script
>
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
tooltip
from
'
~/vue_shared/directives/tooltip
'
;
import
tooltip
from
'
~/vue_shared/directives/tooltip
'
;
import
'
~/lib/utils/datetime_utility
'
;
import
'
~/lib/utils/datetime_utility
'
;
export
default
{
export
default
{
components
:
{
components
:
{
icon
,
icon
,
},
directives
:
{
tooltip
,
},
props
:
{
file
:
{
type
:
Object
,
required
:
true
,
},
},
directives
:
{
},
tooltip
,
computed
:
{
lockTooltip
()
{
return
`Locked by
${
this
.
file
.
file_lock
.
user
.
name
}
`
;
},
},
props
:
{
},
file
:
{
};
type
:
Object
,
required
:
true
,
},
},
computed
:
{
lockTooltip
()
{
return
`Locked by
${
this
.
file
.
file_lock
.
user
.
name
}
`
;
},
},
};
</
script
>
</
script
>
<
template
>
<
template
>
...
...
app/assets/javascripts/ide/components/repo_tabs.vue
View file @
4410a1fa
<
script
>
<
script
>
import
{
mapActions
}
from
'
vuex
'
;
import
{
mapActions
}
from
'
vuex
'
;
import
RepoTab
from
'
./repo_tab.vue
'
;
import
RepoTab
from
'
./repo_tab.vue
'
;
import
EditorMode
from
'
./editor_mode_dropdown.vue
'
;
import
EditorMode
from
'
./editor_mode_dropdown.vue
'
;
export
default
{
export
default
{
components
:
{
components
:
{
RepoTab
,
RepoTab
,
EditorMode
,
EditorMode
,
},
props
:
{
files
:
{
type
:
Array
,
required
:
true
,
},
},
props
:
{
viewer
:
{
files
:
{
type
:
String
,
type
:
Array
,
required
:
true
,
required
:
true
,
},
viewer
:
{
type
:
String
,
required
:
true
,
},
hasChanges
:
{
type
:
Boolean
,
required
:
true
,
},
},
},
data
()
{
hasChanges
:
{
return
{
type
:
Boolean
,
showShadow
:
false
,
required
:
true
,
};
},
},
updated
()
{
mergeRequestId
:
{
if
(
!
this
.
$refs
.
tabsScroller
)
return
;
type
:
String
,
required
:
false
,
this
.
showShadow
=
default
:
''
,
this
.
$refs
.
tabsScroller
.
scrollWidth
>
this
.
$refs
.
tabsScroller
.
offsetWidth
;
},
methods
:
{
...
mapActions
([
'
updateViewer
'
]),
},
},
};
},
data
()
{
return
{
showShadow
:
false
,
};
},
updated
()
{
if
(
!
this
.
$refs
.
tabsScroller
)
return
;
this
.
showShadow
=
this
.
$refs
.
tabsScroller
.
scrollWidth
>
this
.
$refs
.
tabsScroller
.
offsetWidth
;
},
methods
:
{
...
mapActions
([
'
updateViewer
'
]),
},
};
</
script
>
</
script
>
<
template
>
<
template
>
...
@@ -55,6 +59,7 @@
...
@@ -55,6 +59,7 @@
:viewer=
"viewer"
:viewer=
"viewer"
:show-shadow=
"showShadow"
:show-shadow=
"showShadow"
:has-changes=
"hasChanges"
:has-changes=
"hasChanges"
:merge-request-id=
"mergeRequestId"
@
click=
"updateViewer"
@
click=
"updateViewer"
/>
/>
</div>
</div>
...
...
app/assets/javascripts/ide/ide_router.js
View file @
4410a1fa
...
@@ -44,7 +44,7 @@ const router = new VueRouter({
...
@@ -44,7 +44,7 @@ const router = new VueRouter({
component
:
EmptyRouterComponent
,
component
:
EmptyRouterComponent
,
},
},
{
{
path
:
'
m
r
/:mrid
'
,
path
:
'
m
erge_requests
/:mrid
'
,
component
:
EmptyRouterComponent
,
component
:
EmptyRouterComponent
,
},
},
],
],
...
@@ -76,9 +76,7 @@ router.beforeEach((to, from, next) => {
...
@@ -76,9 +76,7 @@ router.beforeEach((to, from, next) => {
.
then
(()
=>
{
.
then
(()
=>
{
if
(
to
.
params
[
0
])
{
if
(
to
.
params
[
0
])
{
const
path
=
const
path
=
to
.
params
[
0
].
slice
(
-
1
)
===
'
/
'
to
.
params
[
0
].
slice
(
-
1
)
===
'
/
'
?
to
.
params
[
0
].
slice
(
0
,
-
1
)
:
to
.
params
[
0
];
?
to
.
params
[
0
].
slice
(
0
,
-
1
)
:
to
.
params
[
0
];
const
treeEntry
=
store
.
state
.
entries
[
path
];
const
treeEntry
=
store
.
state
.
entries
[
path
];
if
(
treeEntry
)
{
if
(
treeEntry
)
{
store
.
dispatch
(
'
handleTreeEntryAction
'
,
treeEntry
);
store
.
dispatch
(
'
handleTreeEntryAction
'
,
treeEntry
);
...
@@ -96,6 +94,60 @@ router.beforeEach((to, from, next) => {
...
@@ -96,6 +94,60 @@ router.beforeEach((to, from, next) => {
);
);
throw
e
;
throw
e
;
});
});
}
else
if
(
to
.
params
.
mrid
)
{
store
.
dispatch
(
'
updateViewer
'
,
'
mrdiff
'
);
store
.
dispatch
(
'
getMergeRequestData
'
,
{
projectId
:
fullProjectId
,
mergeRequestId
:
to
.
params
.
mrid
,
})
.
then
(
mr
=>
{
store
.
dispatch
(
'
getBranchData
'
,
{
projectId
:
fullProjectId
,
branchId
:
mr
.
source_branch
,
});
return
store
.
dispatch
(
'
getFiles
'
,
{
projectId
:
fullProjectId
,
branchId
:
mr
.
source_branch
,
});
})
.
then
(()
=>
store
.
dispatch
(
'
getMergeRequestVersions
'
,
{
projectId
:
fullProjectId
,
mergeRequestId
:
to
.
params
.
mrid
,
}),
)
.
then
(()
=>
store
.
dispatch
(
'
getMergeRequestChanges
'
,
{
projectId
:
fullProjectId
,
mergeRequestId
:
to
.
params
.
mrid
,
}),
)
.
then
(
mrChanges
=>
{
mrChanges
.
changes
.
forEach
((
change
,
ind
)
=>
{
const
changeTreeEntry
=
store
.
state
.
entries
[
change
.
new_path
];
if
(
changeTreeEntry
)
{
store
.
dispatch
(
'
setFileMrChange
'
,
{
file
:
changeTreeEntry
,
mrChange
:
change
,
});
if
(
ind
<
10
)
{
store
.
dispatch
(
'
getFileData
'
,
{
path
:
change
.
new_path
,
makeFileActive
:
ind
===
0
,
});
}
}
});
})
.
catch
(
e
=>
{
flash
(
'
Error while loading the merge request. Please try again.
'
);
throw
e
;
});
}
}
})
})
.
catch
(
e
=>
{
.
catch
(
e
=>
{
...
...
app/assets/javascripts/ide/lib/common/model.js
View file @
4410a1fa
...
@@ -21,6 +21,15 @@ export default class Model {
...
@@ -21,6 +21,15 @@ export default class Model {
new
this
.
monaco
.
Uri
(
null
,
null
,
this
.
file
.
path
),
new
this
.
monaco
.
Uri
(
null
,
null
,
this
.
file
.
path
),
)),
)),
);
);
if
(
this
.
file
.
mrChange
)
{
this
.
disposable
.
add
(
(
this
.
baseModel
=
this
.
monaco
.
editor
.
createModel
(
this
.
file
.
baseRaw
,
undefined
,
new
this
.
monaco
.
Uri
(
null
,
null
,
`target/
${
this
.
file
.
path
}
`
),
)),
);
}
this
.
events
=
new
Map
();
this
.
events
=
new
Map
();
...
@@ -28,10 +37,7 @@ export default class Model {
...
@@ -28,10 +37,7 @@ export default class Model {
this
.
dispose
=
this
.
dispose
.
bind
(
this
);
this
.
dispose
=
this
.
dispose
.
bind
(
this
);
eventHub
.
$on
(
`editor.update.model.dispose.
${
this
.
file
.
path
}
`
,
this
.
dispose
);
eventHub
.
$on
(
`editor.update.model.dispose.
${
this
.
file
.
path
}
`
,
this
.
dispose
);
eventHub
.
$on
(
eventHub
.
$on
(
`editor.update.model.content.
${
this
.
file
.
path
}
`
,
this
.
updateContent
);
`editor.update.model.content.
${
this
.
file
.
path
}
`
,
this
.
updateContent
,
);
}
}
get
url
()
{
get
url
()
{
...
@@ -58,6 +64,10 @@ export default class Model {
...
@@ -58,6 +64,10 @@ export default class Model {
return
this
.
originalModel
;
return
this
.
originalModel
;
}
}
getBaseModel
()
{
return
this
.
baseModel
;
}
setValue
(
value
)
{
setValue
(
value
)
{
this
.
getModel
().
setValue
(
value
);
this
.
getModel
().
setValue
(
value
);
}
}
...
@@ -78,13 +88,7 @@ export default class Model {
...
@@ -78,13 +88,7 @@ export default class Model {
this
.
disposable
.
dispose
();
this
.
disposable
.
dispose
();
this
.
events
.
clear
();
this
.
events
.
clear
();
eventHub
.
$off
(
eventHub
.
$off
(
`editor.update.model.dispose.
${
this
.
file
.
path
}
`
,
this
.
dispose
);
`editor.update.model.dispose.
${
this
.
file
.
path
}
`
,
eventHub
.
$off
(
`editor.update.model.content.
${
this
.
file
.
path
}
`
,
this
.
updateContent
);
this
.
dispose
,
);
eventHub
.
$off
(
`editor.update.model.content.
${
this
.
file
.
path
}
`
,
this
.
updateContent
,
);
}
}
}
}
app/assets/javascripts/ide/lib/editor.js
View file @
4410a1fa
...
@@ -109,11 +109,19 @@ export default class Editor {
...
@@ -109,11 +109,19 @@ export default class Editor {
if
(
this
.
dirtyDiffController
)
this
.
dirtyDiffController
.
reDecorate
(
model
);
if
(
this
.
dirtyDiffController
)
this
.
dirtyDiffController
.
reDecorate
(
model
);
}
}
attachMergeRequestModel
(
model
)
{
this
.
instance
.
setModel
({
original
:
model
.
getBaseModel
(),
modified
:
model
.
getModel
(),
});
this
.
monaco
.
editor
.
createDiffNavigator
(
this
.
instance
,
{
alwaysRevealFirst
:
true
,
});
}
setupMonacoTheme
()
{
setupMonacoTheme
()
{
this
.
monaco
.
editor
.
defineTheme
(
this
.
monaco
.
editor
.
defineTheme
(
gitlabTheme
.
themeName
,
gitlabTheme
.
monacoTheme
);
gitlabTheme
.
themeName
,
gitlabTheme
.
monacoTheme
,
);
this
.
monaco
.
editor
.
setTheme
(
'
gitlab
'
);
this
.
monaco
.
editor
.
setTheme
(
'
gitlab
'
);
}
}
...
@@ -161,8 +169,6 @@ export default class Editor {
...
@@ -161,8 +169,6 @@ export default class Editor {
onPositionChange
(
cb
)
{
onPositionChange
(
cb
)
{
if
(
!
this
.
instance
.
onDidChangeCursorPosition
)
return
;
if
(
!
this
.
instance
.
onDidChangeCursorPosition
)
return
;
this
.
disposable
.
add
(
this
.
disposable
.
add
(
this
.
instance
.
onDidChangeCursorPosition
(
e
=>
cb
(
this
.
instance
,
e
)));
this
.
instance
.
onDidChangeCursorPosition
(
e
=>
cb
(
this
.
instance
,
e
)),
);
}
}
}
}
app/assets/javascripts/ide/services/index.js
View file @
4410a1fa
...
@@ -20,12 +20,35 @@ export default {
...
@@ -20,12 +20,35 @@ export default {
return
Promise
.
resolve
(
file
.
raw
);
return
Promise
.
resolve
(
file
.
raw
);
}
}
return
Vue
.
http
.
get
(
file
.
rawPath
,
{
params
:
{
format
:
'
json
'
}
})
return
Vue
.
http
.
get
(
file
.
rawPath
,
{
params
:
{
format
:
'
json
'
}
}).
then
(
res
=>
res
.
text
());
},
getBaseRawFileData
(
file
,
sha
)
{
if
(
file
.
tempFile
)
{
return
Promise
.
resolve
(
file
.
baseRaw
);
}
if
(
file
.
baseRaw
)
{
return
Promise
.
resolve
(
file
.
baseRaw
);
}
return
Vue
.
http
.
get
(
file
.
rawPath
.
replace
(
`/raw/
${
file
.
branchId
}
/
${
file
.
path
}
`
,
`/raw/
${
sha
}
/
${
file
.
path
}
`
),
{
params
:
{
format
:
'
json
'
},
})
.
then
(
res
=>
res
.
text
());
.
then
(
res
=>
res
.
text
());
},
},
getProjectData
(
namespace
,
project
)
{
getProjectData
(
namespace
,
project
)
{
return
Api
.
project
(
`
${
namespace
}
/
${
project
}
`
);
return
Api
.
project
(
`
${
namespace
}
/
${
project
}
`
);
},
},
getProjectMergeRequestData
(
projectId
,
mergeRequestId
)
{
return
Api
.
mergeRequest
(
projectId
,
mergeRequestId
);
},
getProjectMergeRequestChanges
(
projectId
,
mergeRequestId
)
{
return
Api
.
mergeRequestChanges
(
projectId
,
mergeRequestId
);
},
getProjectMergeRequestVersions
(
projectId
,
mergeRequestId
)
{
return
Api
.
mergeRequestVersions
(
projectId
,
mergeRequestId
);
},
getBranchData
(
projectId
,
currentBranchId
)
{
getBranchData
(
projectId
,
currentBranchId
)
{
return
Api
.
branchSingle
(
projectId
,
currentBranchId
);
return
Api
.
branchSingle
(
projectId
,
currentBranchId
);
},
},
...
...
app/assets/javascripts/ide/stores/actions.js
View file @
4410a1fa
...
@@ -6,8 +6,7 @@ import FilesDecoratorWorker from './workers/files_decorator_worker';
...
@@ -6,8 +6,7 @@ import FilesDecoratorWorker from './workers/files_decorator_worker';
export
const
redirectToUrl
=
(
_
,
url
)
=>
visitUrl
(
url
);
export
const
redirectToUrl
=
(
_
,
url
)
=>
visitUrl
(
url
);
export
const
setInitialData
=
({
commit
},
data
)
=>
export
const
setInitialData
=
({
commit
},
data
)
=>
commit
(
types
.
SET_INITIAL_DATA
,
data
);
commit
(
types
.
SET_INITIAL_DATA
,
data
);
export
const
discardAllChanges
=
({
state
,
commit
,
dispatch
})
=>
{
export
const
discardAllChanges
=
({
state
,
commit
,
dispatch
})
=>
{
state
.
changedFiles
.
forEach
(
file
=>
{
state
.
changedFiles
.
forEach
(
file
=>
{
...
@@ -43,14 +42,11 @@ export const createTempEntry = (
...
@@ -43,14 +42,11 @@ export const createTempEntry = (
)
=>
)
=>
new
Promise
(
resolve
=>
{
new
Promise
(
resolve
=>
{
const
worker
=
new
FilesDecoratorWorker
();
const
worker
=
new
FilesDecoratorWorker
();
const
fullName
=
const
fullName
=
name
.
slice
(
-
1
)
!==
'
/
'
&&
type
===
'
tree
'
?
`
${
name
}
/`
:
name
;
name
.
slice
(
-
1
)
!==
'
/
'
&&
type
===
'
tree
'
?
`
${
name
}
/`
:
name
;
if
(
state
.
entries
[
name
])
{
if
(
state
.
entries
[
name
])
{
flash
(
flash
(
`The name "
${
name
`The name "
${
name
.
split
(
'
/
'
).
pop
()}
" is already taken in this directory.`
,
.
split
(
'
/
'
)
.
pop
()}
" is already taken in this directory.`
,
'
alert
'
,
'
alert
'
,
document
,
document
,
null
,
null
,
...
@@ -119,3 +115,4 @@ export const updateDelayViewerUpdated = ({ commit }, delay) => {
...
@@ -119,3 +115,4 @@ export const updateDelayViewerUpdated = ({ commit }, delay) => {
export
*
from
'
./actions/tree
'
;
export
*
from
'
./actions/tree
'
;
export
*
from
'
./actions/file
'
;
export
*
from
'
./actions/file
'
;
export
*
from
'
./actions/project
'
;
export
*
from
'
./actions/project
'
;
export
*
from
'
./actions/merge_request
'
;
app/assets/javascripts/ide/stores/actions/file.js
View file @
4410a1fa
...
@@ -46,53 +46,63 @@ export const setFileActive = ({ commit, state, getters, dispatch }, path) => {
...
@@ -46,53 +46,63 @@ export const setFileActive = ({ commit, state, getters, dispatch }, path) => {
commit
(
types
.
SET_CURRENT_BRANCH
,
file
.
branchId
);
commit
(
types
.
SET_CURRENT_BRANCH
,
file
.
branchId
);
};
};
export
const
getFileData
=
({
state
,
commit
,
dispatch
},
file
)
=>
{
export
const
getFileData
=
({
state
,
commit
,
dispatch
},
{
path
,
makeFileActive
=
true
})
=>
{
const
file
=
state
.
entries
[
path
];
commit
(
types
.
TOGGLE_LOADING
,
{
entry
:
file
});
commit
(
types
.
TOGGLE_LOADING
,
{
entry
:
file
});
return
service
return
service
.
getFileData
(
file
.
url
)
.
getFileData
(
file
.
url
)
.
then
(
res
=>
{
.
then
(
res
=>
{
const
pageTitle
=
decodeURI
(
normalizeHeaders
(
res
.
headers
)[
'
PAGE-TITLE
'
]);
const
pageTitle
=
decodeURI
(
normalizeHeaders
(
res
.
headers
)[
'
PAGE-TITLE
'
]);
setPageTitle
(
pageTitle
);
setPageTitle
(
pageTitle
);
return
res
.
json
();
return
res
.
json
();
})
})
.
then
(
data
=>
{
.
then
(
data
=>
{
commit
(
types
.
SET_FILE_DATA
,
{
data
,
file
});
commit
(
types
.
SET_FILE_DATA
,
{
data
,
file
});
commit
(
types
.
TOGGLE_FILE_OPEN
,
file
.
path
);
commit
(
types
.
TOGGLE_FILE_OPEN
,
path
);
dispatch
(
'
setFileActive
'
,
file
.
path
);
if
(
makeFileActive
)
dispatch
(
'
setFileActive
'
,
path
);
commit
(
types
.
TOGGLE_LOADING
,
{
entry
:
file
});
commit
(
types
.
TOGGLE_LOADING
,
{
entry
:
file
});
})
})
.
catch
(()
=>
{
.
catch
(()
=>
{
commit
(
types
.
TOGGLE_LOADING
,
{
entry
:
file
});
commit
(
types
.
TOGGLE_LOADING
,
{
entry
:
file
});
flash
(
flash
(
'
Error loading file data. Please try again.
'
,
'
alert
'
,
document
,
null
,
false
,
true
);
'
Error loading file data. Please try again.
'
,
'
alert
'
,
document
,
null
,
false
,
true
,
);
});
});
};
};
export
const
getRawFileData
=
({
commit
,
dispatch
},
file
)
=>
export
const
setFileMrChange
=
({
state
,
commit
},
{
file
,
mrChange
})
=>
{
service
commit
(
types
.
SET_FILE_MERGE_REQUEST_CHANGE
,
{
file
,
mrChange
});
.
getRawFileData
(
file
)
};
.
then
(
raw
=>
{
commit
(
types
.
SET_FILE_RAW_DATA
,
{
file
,
raw
});
export
const
getRawFileData
=
({
state
,
commit
,
dispatch
},
{
path
,
baseSha
})
=>
{
})
const
file
=
state
.
entries
[
path
];
.
catch
(()
=>
return
new
Promise
((
resolve
,
reject
)
=>
{
flash
(
service
'
Error loading file content. Please try again.
'
,
.
getRawFileData
(
file
)
'
alert
'
,
.
then
(
raw
=>
{
document
,
commit
(
types
.
SET_FILE_RAW_DATA
,
{
file
,
raw
});
null
,
if
(
file
.
mrChange
&&
file
.
mrChange
.
new_file
===
false
)
{
false
,
service
true
,
.
getBaseRawFileData
(
file
,
baseSha
)
),
.
then
(
baseRaw
=>
{
);
commit
(
types
.
SET_FILE_BASE_RAW_DATA
,
{
file
,
baseRaw
,
});
resolve
(
raw
);
})
.
catch
(
e
=>
{
reject
(
e
);
});
}
else
{
resolve
(
raw
);
}
})
.
catch
(()
=>
{
flash
(
'
Error loading file content. Please try again.
'
);
reject
();
});
});
};
export
const
changeFileContent
=
({
state
,
commit
},
{
path
,
content
})
=>
{
export
const
changeFileContent
=
({
state
,
commit
},
{
path
,
content
})
=>
{
const
file
=
state
.
entries
[
path
];
const
file
=
state
.
entries
[
path
];
...
@@ -119,10 +129,7 @@ export const setFileEOL = ({ getters, commit }, { eol }) => {
...
@@ -119,10 +129,7 @@ export const setFileEOL = ({ getters, commit }, { eol }) => {
}
}
};
};
export
const
setEditorPosition
=
(
export
const
setEditorPosition
=
({
getters
,
commit
},
{
editorRow
,
editorColumn
})
=>
{
{
getters
,
commit
},
{
editorRow
,
editorColumn
},
)
=>
{
if
(
getters
.
activeFile
)
{
if
(
getters
.
activeFile
)
{
commit
(
types
.
SET_FILE_POSITION
,
{
commit
(
types
.
SET_FILE_POSITION
,
{
file
:
getters
.
activeFile
,
file
:
getters
.
activeFile
,
...
...
app/assets/javascripts/ide/stores/actions/merge_request.js
0 → 100644
View file @
4410a1fa
import
flash
from
'
~/flash
'
;
import
service
from
'
../../services
'
;
import
*
as
types
from
'
../mutation_types
'
;
export
const
getMergeRequestData
=
(
{
commit
,
state
,
dispatch
},
{
projectId
,
mergeRequestId
,
force
=
false
}
=
{},
)
=>
new
Promise
((
resolve
,
reject
)
=>
{
if
(
!
state
.
projects
[
projectId
].
mergeRequests
[
mergeRequestId
]
||
force
)
{
service
.
getProjectMergeRequestData
(
projectId
,
mergeRequestId
)
.
then
(
res
=>
res
.
data
)
.
then
(
data
=>
{
commit
(
types
.
SET_MERGE_REQUEST
,
{
projectPath
:
projectId
,
mergeRequestId
,
mergeRequest
:
data
,
});
if
(
!
state
.
currentMergeRequestId
)
{
commit
(
types
.
SET_CURRENT_MERGE_REQUEST
,
mergeRequestId
);
}
resolve
(
data
);
})
.
catch
(()
=>
{
flash
(
'
Error loading merge request data. Please try again.
'
);
reject
(
new
Error
(
`Merge Request not loaded
${
projectId
}
`
));
});
}
else
{
resolve
(
state
.
projects
[
projectId
].
mergeRequests
[
mergeRequestId
]);
}
});
export
const
getMergeRequestChanges
=
(
{
commit
,
state
,
dispatch
},
{
projectId
,
mergeRequestId
,
force
=
false
}
=
{},
)
=>
new
Promise
((
resolve
,
reject
)
=>
{
if
(
!
state
.
projects
[
projectId
].
mergeRequests
[
mergeRequestId
].
changes
.
length
||
force
)
{
service
.
getProjectMergeRequestChanges
(
projectId
,
mergeRequestId
)
.
then
(
res
=>
res
.
data
)
.
then
(
data
=>
{
commit
(
types
.
SET_MERGE_REQUEST_CHANGES
,
{
projectPath
:
projectId
,
mergeRequestId
,
changes
:
data
,
});
resolve
(
data
);
})
.
catch
(()
=>
{
flash
(
'
Error loading merge request changes. Please try again.
'
);
reject
(
new
Error
(
`Merge Request Changes not loaded
${
projectId
}
`
));
});
}
else
{
resolve
(
state
.
projects
[
projectId
].
mergeRequests
[
mergeRequestId
].
changes
);
}
});
export
const
getMergeRequestVersions
=
(
{
commit
,
state
,
dispatch
},
{
projectId
,
mergeRequestId
,
force
=
false
}
=
{},
)
=>
new
Promise
((
resolve
,
reject
)
=>
{
if
(
!
state
.
projects
[
projectId
].
mergeRequests
[
mergeRequestId
].
versions
.
length
||
force
)
{
service
.
getProjectMergeRequestVersions
(
projectId
,
mergeRequestId
)
.
then
(
res
=>
res
.
data
)
.
then
(
data
=>
{
commit
(
types
.
SET_MERGE_REQUEST_VERSIONS
,
{
projectPath
:
projectId
,
mergeRequestId
,
versions
:
data
,
});
resolve
(
data
);
})
.
catch
(()
=>
{
flash
(
'
Error loading merge request versions. Please try again.
'
);
reject
(
new
Error
(
`Merge Request Versions not loaded
${
projectId
}
`
));
});
}
else
{
resolve
(
state
.
projects
[
projectId
].
mergeRequests
[
mergeRequestId
].
versions
);
}
});
app/assets/javascripts/ide/stores/actions/tree.js
View file @
4410a1fa
...
@@ -2,9 +2,7 @@ import { normalizeHeaders } from '~/lib/utils/common_utils';
...
@@ -2,9 +2,7 @@ import { normalizeHeaders } from '~/lib/utils/common_utils';
import
flash
from
'
~/flash
'
;
import
flash
from
'
~/flash
'
;
import
service
from
'
../../services
'
;
import
service
from
'
../../services
'
;
import
*
as
types
from
'
../mutation_types
'
;
import
*
as
types
from
'
../mutation_types
'
;
import
{
import
{
findEntry
}
from
'
../utils
'
;
findEntry
,
}
from
'
../utils
'
;
import
FilesDecoratorWorker
from
'
../workers/files_decorator_worker
'
;
import
FilesDecoratorWorker
from
'
../workers/files_decorator_worker
'
;
export
const
toggleTreeOpen
=
({
commit
,
dispatch
},
path
)
=>
{
export
const
toggleTreeOpen
=
({
commit
,
dispatch
},
path
)
=>
{
...
@@ -21,23 +19,24 @@ export const handleTreeEntryAction = ({ commit, dispatch }, row) => {
...
@@ -21,23 +19,24 @@ export const handleTreeEntryAction = ({ commit, dispatch }, row) => {
dispatch
(
'
setFileActive
'
,
row
.
path
);
dispatch
(
'
setFileActive
'
,
row
.
path
);
}
else
{
}
else
{
dispatch
(
'
getFileData
'
,
row
);
dispatch
(
'
getFileData
'
,
{
path
:
row
.
path
}
);
}
}
};
};
export
const
getLastCommitData
=
({
state
,
commit
,
dispatch
,
getters
},
tree
=
state
)
=>
{
export
const
getLastCommitData
=
({
state
,
commit
,
dispatch
,
getters
},
tree
=
state
)
=>
{
if
(
!
tree
||
tree
.
lastCommitPath
===
null
||
!
tree
.
lastCommitPath
)
return
;
if
(
!
tree
||
tree
.
lastCommitPath
===
null
||
!
tree
.
lastCommitPath
)
return
;
service
.
getTreeLastCommit
(
tree
.
lastCommitPath
)
service
.
then
((
res
)
=>
{
.
getTreeLastCommit
(
tree
.
lastCommitPath
)
.
then
(
res
=>
{
const
lastCommitPath
=
normalizeHeaders
(
res
.
headers
)[
'
MORE-LOGS-URL
'
]
||
null
;
const
lastCommitPath
=
normalizeHeaders
(
res
.
headers
)[
'
MORE-LOGS-URL
'
]
||
null
;
commit
(
types
.
SET_LAST_COMMIT_URL
,
{
tree
,
url
:
lastCommitPath
});
commit
(
types
.
SET_LAST_COMMIT_URL
,
{
tree
,
url
:
lastCommitPath
});
return
res
.
json
();
return
res
.
json
();
})
})
.
then
(
(
data
)
=>
{
.
then
(
data
=>
{
data
.
forEach
(
(
lastCommit
)
=>
{
data
.
forEach
(
lastCommit
=>
{
const
entry
=
findEntry
(
tree
.
tree
,
lastCommit
.
type
,
lastCommit
.
file_name
);
const
entry
=
findEntry
(
tree
.
tree
,
lastCommit
.
type
,
lastCommit
.
file_name
);
if
(
entry
)
{
if
(
entry
)
{
...
@@ -50,44 +49,47 @@ export const getLastCommitData = ({ state, commit, dispatch, getters }, tree = s
...
@@ -50,44 +49,47 @@ export const getLastCommitData = ({ state, commit, dispatch, getters }, tree = s
.
catch
(()
=>
flash
(
'
Error fetching log data.
'
,
'
alert
'
,
document
,
null
,
false
,
true
));
.
catch
(()
=>
flash
(
'
Error fetching log data.
'
,
'
alert
'
,
document
,
null
,
false
,
true
));
};
};
export
const
getFiles
=
(
export
const
getFiles
=
({
state
,
commit
,
dispatch
},
{
projectId
,
branchId
}
=
{})
=>
{
state
,
commit
,
dispatch
},
new
Promise
((
resolve
,
reject
)
=>
{
{
projectId
,
branchId
}
=
{},
if
(
!
state
.
trees
[
`
${
projectId
}
/
${
branchId
}
`
])
{
)
=>
new
Promise
((
resolve
,
reject
)
=>
{
const
selectedProject
=
state
.
projects
[
projectId
];
if
(
!
state
.
trees
[
`
${
projectId
}
/
${
branchId
}
`
])
{
commit
(
types
.
CREATE_TREE
,
{
treePath
:
`
${
projectId
}
/
${
branchId
}
`
});
const
selectedProject
=
state
.
projects
[
projectId
];
commit
(
types
.
CREATE_TREE
,
{
treePath
:
`
${
projectId
}
/
${
branchId
}
`
});
service
.
getFiles
(
selectedProject
.
web_url
,
branchId
)
service
.
then
(
res
=>
res
.
json
())
.
getFiles
(
selectedProject
.
web_url
,
branchId
)
.
then
(
data
=>
{
.
then
(
res
=>
res
.
json
())
const
worker
=
new
FilesDecoratorWorker
();
.
then
((
data
)
=>
{
worker
.
addEventListener
(
'
message
'
,
e
=>
{
const
worker
=
new
FilesDecoratorWorker
();
const
{
entries
,
treeList
}
=
e
.
data
;
worker
.
addEventListener
(
'
message
'
,
(
e
)
=>
{
const
selectedTree
=
state
.
trees
[
`
${
projectId
}
/
${
branchId
}
`
];
const
{
entries
,
treeList
}
=
e
.
data
;
const
selectedTree
=
state
.
trees
[
`
${
projectId
}
/
${
branchId
}
`
];
commit
(
types
.
SET_ENTRIES
,
entries
);
commit
(
types
.
SET_DIRECTORY_DATA
,
{
commit
(
types
.
SET_ENTRIES
,
entries
);
treePath
:
`
${
projectId
}
/
${
branchId
}
`
,
commit
(
types
.
SET_DIRECTORY_DATA
,
{
treePath
:
`
${
projectId
}
/
${
branchId
}
`
,
data
:
treeList
});
data
:
treeList
,
commit
(
types
.
TOGGLE_LOADING
,
{
entry
:
selectedTree
,
forceValue
:
false
});
});
commit
(
types
.
TOGGLE_LOADING
,
{
worker
.
terminate
();
entry
:
selectedTree
,
forceValue
:
false
,
resolve
();
});
});
worker
.
terminate
();
worker
.
postMessage
({
data
,
resolve
();
projectId
,
});
branchId
,
worker
.
postMessage
({
data
,
projectId
,
branchId
,
});
})
.
catch
(
e
=>
{
flash
(
'
Error loading tree data. Please try again.
'
,
'
alert
'
,
document
,
null
,
false
,
true
);
reject
(
e
);
});
});
})
}
else
{
.
catch
((
e
)
=>
{
resolve
();
flash
(
'
Error loading tree data. Please try again.
'
,
'
alert
'
,
document
,
null
,
false
,
true
);
}
reject
(
e
);
});
});
}
else
{
resolve
();
}
});
app/assets/javascripts/ide/stores/getters.js
View file @
4410a1fa
export
const
activeFile
=
state
=>
export
const
activeFile
=
state
=>
state
.
openFiles
.
find
(
file
=>
file
.
active
)
||
null
;
state
.
openFiles
.
find
(
file
=>
file
.
active
)
||
null
;
export
const
addedFiles
=
state
=>
state
.
changedFiles
.
filter
(
f
=>
f
.
tempFile
);
export
const
addedFiles
=
state
=>
state
.
changedFiles
.
filter
(
f
=>
f
.
tempFile
);
export
const
modifiedFiles
=
state
=>
export
const
modifiedFiles
=
state
=>
state
.
changedFiles
.
filter
(
f
=>
!
f
.
tempFile
);
state
.
changedFiles
.
filter
(
f
=>
!
f
.
tempFile
);
export
const
projectsWithTrees
=
state
=>
export
const
projectsWithTrees
=
state
=>
Object
.
keys
(
state
.
projects
).
map
(
projectId
=>
{
Object
.
keys
(
state
.
projects
).
map
(
projectId
=>
{
...
@@ -23,8 +21,17 @@ export const projectsWithTrees = state =>
...
@@ -23,8 +21,17 @@ export const projectsWithTrees = state =>
};
};
});
});
export
const
currentMergeRequest
=
state
=>
{
if
(
state
.
projects
[
state
.
currentProjectId
])
{
return
state
.
projects
[
state
.
currentProjectId
].
mergeRequests
[
state
.
currentMergeRequestId
];
}
return
null
;
};
// eslint-disable-next-line no-confusing-arrow
// eslint-disable-next-line no-confusing-arrow
export
const
currentIcon
=
state
=>
export
const
currentIcon
=
state
=>
state
.
rightPanelCollapsed
?
'
angle-double-left
'
:
'
angle-double-right
'
;
state
.
rightPanelCollapsed
?
'
angle-double-left
'
:
'
angle-double-right
'
;
export
const
hasChanges
=
state
=>
!!
state
.
changedFiles
.
length
;
export
const
hasChanges
=
state
=>
!!
state
.
changedFiles
.
length
;
export
const
hasMergeRequest
=
state
=>
!!
state
.
currentMergeRequestId
;
app/assets/javascripts/ide/stores/mutation_types.js
View file @
4410a1fa
...
@@ -11,6 +11,12 @@ export const SET_PROJECT = 'SET_PROJECT';
...
@@ -11,6 +11,12 @@ export const SET_PROJECT = 'SET_PROJECT';
export
const
SET_CURRENT_PROJECT
=
'
SET_CURRENT_PROJECT
'
;
export
const
SET_CURRENT_PROJECT
=
'
SET_CURRENT_PROJECT
'
;
export
const
TOGGLE_PROJECT_OPEN
=
'
TOGGLE_PROJECT_OPEN
'
;
export
const
TOGGLE_PROJECT_OPEN
=
'
TOGGLE_PROJECT_OPEN
'
;
// Merge Request Mutation Types
export
const
SET_MERGE_REQUEST
=
'
SET_MERGE_REQUEST
'
;
export
const
SET_CURRENT_MERGE_REQUEST
=
'
SET_CURRENT_MERGE_REQUEST
'
;
export
const
SET_MERGE_REQUEST_CHANGES
=
'
SET_MERGE_REQUEST_CHANGES
'
;
export
const
SET_MERGE_REQUEST_VERSIONS
=
'
SET_MERGE_REQUEST_VERSIONS
'
;
// Branch Mutation Types
// Branch Mutation Types
export
const
SET_BRANCH
=
'
SET_BRANCH
'
;
export
const
SET_BRANCH
=
'
SET_BRANCH
'
;
export
const
SET_BRANCH_WORKING_REFERENCE
=
'
SET_BRANCH_WORKING_REFERENCE
'
;
export
const
SET_BRANCH_WORKING_REFERENCE
=
'
SET_BRANCH_WORKING_REFERENCE
'
;
...
@@ -28,6 +34,7 @@ export const SET_FILE_DATA = 'SET_FILE_DATA';
...
@@ -28,6 +34,7 @@ export const SET_FILE_DATA = 'SET_FILE_DATA';
export
const
TOGGLE_FILE_OPEN
=
'
TOGGLE_FILE_OPEN
'
;
export
const
TOGGLE_FILE_OPEN
=
'
TOGGLE_FILE_OPEN
'
;
export
const
SET_FILE_ACTIVE
=
'
SET_FILE_ACTIVE
'
;
export
const
SET_FILE_ACTIVE
=
'
SET_FILE_ACTIVE
'
;
export
const
SET_FILE_RAW_DATA
=
'
SET_FILE_RAW_DATA
'
;
export
const
SET_FILE_RAW_DATA
=
'
SET_FILE_RAW_DATA
'
;
export
const
SET_FILE_BASE_RAW_DATA
=
'
SET_FILE_BASE_RAW_DATA
'
;
export
const
UPDATE_FILE_CONTENT
=
'
UPDATE_FILE_CONTENT
'
;
export
const
UPDATE_FILE_CONTENT
=
'
UPDATE_FILE_CONTENT
'
;
export
const
SET_FILE_LANGUAGE
=
'
SET_FILE_LANGUAGE
'
;
export
const
SET_FILE_LANGUAGE
=
'
SET_FILE_LANGUAGE
'
;
export
const
SET_FILE_POSITION
=
'
SET_FILE_POSITION
'
;
export
const
SET_FILE_POSITION
=
'
SET_FILE_POSITION
'
;
...
@@ -39,5 +46,6 @@ export const TOGGLE_FILE_CHANGED = 'TOGGLE_FILE_CHANGED';
...
@@ -39,5 +46,6 @@ export const TOGGLE_FILE_CHANGED = 'TOGGLE_FILE_CHANGED';
export
const
SET_CURRENT_BRANCH
=
'
SET_CURRENT_BRANCH
'
;
export
const
SET_CURRENT_BRANCH
=
'
SET_CURRENT_BRANCH
'
;
export
const
SET_ENTRIES
=
'
SET_ENTRIES
'
;
export
const
SET_ENTRIES
=
'
SET_ENTRIES
'
;
export
const
CREATE_TMP_ENTRY
=
'
CREATE_TMP_ENTRY
'
;
export
const
CREATE_TMP_ENTRY
=
'
CREATE_TMP_ENTRY
'
;
export
const
SET_FILE_MERGE_REQUEST_CHANGE
=
'
SET_FILE_MERGE_REQUEST_CHANGE
'
;
export
const
UPDATE_VIEWER
=
'
UPDATE_VIEWER
'
;
export
const
UPDATE_VIEWER
=
'
UPDATE_VIEWER
'
;
export
const
UPDATE_DELAY_VIEWER_CHANGE
=
'
UPDATE_DELAY_VIEWER_CHANGE
'
;
export
const
UPDATE_DELAY_VIEWER_CHANGE
=
'
UPDATE_DELAY_VIEWER_CHANGE
'
;
app/assets/javascripts/ide/stores/mutations.js
View file @
4410a1fa
import
*
as
types
from
'
./mutation_types
'
;
import
*
as
types
from
'
./mutation_types
'
;
import
projectMutations
from
'
./mutations/project
'
;
import
projectMutations
from
'
./mutations/project
'
;
import
mergeRequestMutation
from
'
./mutations/merge_request
'
;
import
fileMutations
from
'
./mutations/file
'
;
import
fileMutations
from
'
./mutations/file
'
;
import
treeMutations
from
'
./mutations/tree
'
;
import
treeMutations
from
'
./mutations/tree
'
;
import
branchMutations
from
'
./mutations/branch
'
;
import
branchMutations
from
'
./mutations/branch
'
;
...
@@ -11,10 +12,7 @@ export default {
...
@@ -11,10 +12,7 @@ export default {
[
types
.
TOGGLE_LOADING
](
state
,
{
entry
,
forceValue
=
undefined
})
{
[
types
.
TOGGLE_LOADING
](
state
,
{
entry
,
forceValue
=
undefined
})
{
if
(
entry
.
path
)
{
if
(
entry
.
path
)
{
Object
.
assign
(
state
.
entries
[
entry
.
path
],
{
Object
.
assign
(
state
.
entries
[
entry
.
path
],
{
loading
:
loading
:
forceValue
!==
undefined
?
forceValue
:
!
state
.
entries
[
entry
.
path
].
loading
,
forceValue
!==
undefined
?
forceValue
:
!
state
.
entries
[
entry
.
path
].
loading
,
});
});
}
else
{
}
else
{
Object
.
assign
(
entry
,
{
Object
.
assign
(
entry
,
{
...
@@ -83,9 +81,7 @@ export default {
...
@@ -83,9 +81,7 @@ export default {
if
(
!
foundEntry
)
{
if
(
!
foundEntry
)
{
Object
.
assign
(
state
.
trees
[
`
${
projectId
}
/
${
branchId
}
`
],
{
Object
.
assign
(
state
.
trees
[
`
${
projectId
}
/
${
branchId
}
`
],
{
tree
:
state
.
trees
[
`
${
projectId
}
/
${
branchId
}
`
].
tree
.
concat
(
tree
:
state
.
trees
[
`
${
projectId
}
/
${
branchId
}
`
].
tree
.
concat
(
data
.
treeList
),
data
.
treeList
,
),
});
});
}
}
},
},
...
@@ -100,6 +96,7 @@ export default {
...
@@ -100,6 +96,7 @@ export default {
});
});
},
},
...
projectMutations
,
...
projectMutations
,
...
mergeRequestMutation
,
...
fileMutations
,
...
fileMutations
,
...
treeMutations
,
...
treeMutations
,
...
branchMutations
,
...
branchMutations
,
...
...
app/assets/javascripts/ide/stores/mutations/file.js
View file @
4410a1fa
...
@@ -28,6 +28,8 @@ export default {
...
@@ -28,6 +28,8 @@ export default {
rawPath
:
data
.
raw_path
,
rawPath
:
data
.
raw_path
,
binary
:
data
.
binary
,
binary
:
data
.
binary
,
renderError
:
data
.
render_error
,
renderError
:
data
.
render_error
,
raw
:
null
,
baseRaw
:
null
,
});
});
},
},
[
types
.
SET_FILE_RAW_DATA
](
state
,
{
file
,
raw
})
{
[
types
.
SET_FILE_RAW_DATA
](
state
,
{
file
,
raw
})
{
...
@@ -35,6 +37,11 @@ export default {
...
@@ -35,6 +37,11 @@ export default {
raw
,
raw
,
});
});
},
},
[
types
.
SET_FILE_BASE_RAW_DATA
](
state
,
{
file
,
baseRaw
})
{
Object
.
assign
(
state
.
entries
[
file
.
path
],
{
baseRaw
,
});
},
[
types
.
UPDATE_FILE_CONTENT
](
state
,
{
path
,
content
})
{
[
types
.
UPDATE_FILE_CONTENT
](
state
,
{
path
,
content
})
{
const
changed
=
content
!==
state
.
entries
[
path
].
raw
;
const
changed
=
content
!==
state
.
entries
[
path
].
raw
;
...
@@ -59,6 +66,11 @@ export default {
...
@@ -59,6 +66,11 @@ export default {
editorColumn
,
editorColumn
,
});
});
},
},
[
types
.
SET_FILE_MERGE_REQUEST_CHANGE
](
state
,
{
file
,
mrChange
})
{
Object
.
assign
(
state
.
entries
[
file
.
path
],
{
mrChange
,
});
},
[
types
.
DISCARD_FILE_CHANGES
](
state
,
path
)
{
[
types
.
DISCARD_FILE_CHANGES
](
state
,
path
)
{
Object
.
assign
(
state
.
entries
[
path
],
{
Object
.
assign
(
state
.
entries
[
path
],
{
content
:
state
.
entries
[
path
].
raw
,
content
:
state
.
entries
[
path
].
raw
,
...
...
app/assets/javascripts/ide/stores/mutations/merge_request.js
0 → 100644
View file @
4410a1fa
import
*
as
types
from
'
../mutation_types
'
;
export
default
{
[
types
.
SET_CURRENT_MERGE_REQUEST
](
state
,
currentMergeRequestId
)
{
Object
.
assign
(
state
,
{
currentMergeRequestId
,
});
},
[
types
.
SET_MERGE_REQUEST
](
state
,
{
projectPath
,
mergeRequestId
,
mergeRequest
})
{
Object
.
assign
(
state
.
projects
[
projectPath
],
{
mergeRequests
:
{
[
mergeRequestId
]:
{
...
mergeRequest
,
active
:
true
,
changes
:
[],
versions
:
[],
baseCommitSha
:
null
,
},
},
});
},
[
types
.
SET_MERGE_REQUEST_CHANGES
](
state
,
{
projectPath
,
mergeRequestId
,
changes
})
{
Object
.
assign
(
state
.
projects
[
projectPath
].
mergeRequests
[
mergeRequestId
],
{
changes
,
});
},
[
types
.
SET_MERGE_REQUEST_VERSIONS
](
state
,
{
projectPath
,
mergeRequestId
,
versions
})
{
Object
.
assign
(
state
.
projects
[
projectPath
].
mergeRequests
[
mergeRequestId
],
{
versions
,
baseCommitSha
:
versions
.
length
?
versions
[
0
].
base_commit_sha
:
null
,
});
},
};
app/assets/javascripts/ide/stores/mutations/project.js
View file @
4410a1fa
...
@@ -11,6 +11,7 @@ export default {
...
@@ -11,6 +11,7 @@ export default {
Object
.
assign
(
project
,
{
Object
.
assign
(
project
,
{
tree
:
[],
tree
:
[],
branches
:
{},
branches
:
{},
mergeRequests
:
{},
active
:
true
,
active
:
true
,
});
});
...
...
app/assets/javascripts/ide/stores/state.js
View file @
4410a1fa
export
default
()
=>
({
export
default
()
=>
({
currentProjectId
:
''
,
currentProjectId
:
''
,
currentBranchId
:
''
,
currentBranchId
:
''
,
currentMergeRequestId
:
''
,
changedFiles
:
[],
changedFiles
:
[],
endpoints
:
{},
endpoints
:
{},
lastCommitMsg
:
''
,
lastCommitMsg
:
''
,
...
...
app/assets/javascripts/ide/stores/utils.js
View file @
4410a1fa
...
@@ -38,7 +38,7 @@ export const dataStructure = () => ({
...
@@ -38,7 +38,7 @@ export const dataStructure = () => ({
eol
:
''
,
eol
:
''
,
});
});
export
const
decorateData
=
(
entity
)
=>
{
export
const
decorateData
=
entity
=>
{
const
{
const
{
id
,
id
,
projectId
,
projectId
,
...
@@ -57,7 +57,6 @@ export const decorateData = (entity) => {
...
@@ -57,7 +57,6 @@ export const decorateData = (entity) => {
base64
=
false
,
base64
=
false
,
file_lock
,
file_lock
,
}
=
entity
;
}
=
entity
;
return
{
return
{
...
@@ -80,17 +79,15 @@ export const decorateData = (entity) => {
...
@@ -80,17 +79,15 @@ export const decorateData = (entity) => {
base64
,
base64
,
file_lock
,
file_lock
,
};
};
};
};
export
const
findEntry
=
(
tree
,
type
,
name
,
prop
=
'
name
'
)
=>
tree
.
find
(
export
const
findEntry
=
(
tree
,
type
,
name
,
prop
=
'
name
'
)
=>
f
=>
f
.
type
===
type
&&
f
[
prop
]
===
name
,
tree
.
find
(
f
=>
f
.
type
===
type
&&
f
[
prop
]
===
name
);
);
export
const
findIndexOfFile
=
(
state
,
file
)
=>
state
.
findIndex
(
f
=>
f
.
path
===
file
.
path
);
export
const
findIndexOfFile
=
(
state
,
file
)
=>
state
.
findIndex
(
f
=>
f
.
path
===
file
.
path
);
export
const
setPageTitle
=
(
title
)
=>
{
export
const
setPageTitle
=
title
=>
{
document
.
title
=
title
;
document
.
title
=
title
;
};
};
...
@@ -120,6 +117,11 @@ const sortTreesByTypeAndName = (a, b) => {
...
@@ -120,6 +117,11 @@ const sortTreesByTypeAndName = (a, b) => {
return
0
;
return
0
;
};
};
export
const
sortTree
=
sortedTree
=>
sortedTree
.
map
(
entity
=>
Object
.
assign
(
entity
,
{
export
const
sortTree
=
sortedTree
=>
tree
:
entity
.
tree
.
length
?
sortTree
(
entity
.
tree
)
:
[],
sortedTree
})).
sort
(
sortTreesByTypeAndName
);
.
map
(
entity
=>
Object
.
assign
(
entity
,
{
tree
:
entity
.
tree
.
length
?
sortTree
(
entity
.
tree
)
:
[],
}),
)
.
sort
(
sortTreesByTypeAndName
);
app/assets/javascripts/lib/utils/url_utility.js
View file @
4410a1fa
...
@@ -51,7 +51,7 @@ export function removeParams(params) {
...
@@ -51,7 +51,7 @@ export function removeParams(params) {
const
url
=
document
.
createElement
(
'
a
'
);
const
url
=
document
.
createElement
(
'
a
'
);
url
.
href
=
window
.
location
.
href
;
url
.
href
=
window
.
location
.
href
;
params
.
forEach
(
(
param
)
=>
{
params
.
forEach
(
param
=>
{
url
.
search
=
removeParamQueryString
(
url
.
search
,
param
);
url
.
search
=
removeParamQueryString
(
url
.
search
,
param
);
});
});
...
@@ -83,3 +83,11 @@ export function refreshCurrentPage() {
...
@@ -83,3 +83,11 @@ export function refreshCurrentPage() {
export
function
redirectTo
(
url
)
{
export
function
redirectTo
(
url
)
{
return
window
.
location
.
assign
(
url
);
return
window
.
location
.
assign
(
url
);
}
}
export
function
webIDEUrl
(
projectUrl
=
undefined
)
{
let
returnUrl
=
`
${
gon
.
relative_url_root
}
/-/ide/`
;
if
(
projectUrl
)
{
returnUrl
+=
`project
${
projectUrl
}
`
;
}
return
returnUrl
;
}
app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
View file @
4410a1fa
<
script
>
<
script
>
import
tooltip
from
'
~/vue_shared/directives/tooltip
'
;
import
tooltip
from
'
~/vue_shared/directives/tooltip
'
;
import
{
n__
}
from
'
~/locale
'
;
import
{
n__
}
from
'
~/locale
'
;
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
{
webIDEUrl
}
from
'
~/lib/utils/url_utility
'
;
import
clipboardButton
from
'
~/vue_shared/components/clipboard_button.vue
'
;
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
clipboardButton
from
'
~/vue_shared/components/clipboard_button.vue
'
;
export
default
{
export
default
{
name
:
'
MRWidgetHeader
'
,
name
:
'
MRWidgetHeader
'
,
directives
:
{
directives
:
{
tooltip
,
tooltip
,
},
components
:
{
icon
,
clipboardButton
,
},
props
:
{
mr
:
{
type
:
Object
,
required
:
true
,
},
},
components
:
{
},
icon
,
computed
:
{
clipboardButton
,
shouldShowCommitsBehindText
()
{
return
this
.
mr
.
divergedCommitsCount
>
0
;
},
},
props
:
{
commitsText
()
{
mr
:
{
return
n__
(
'
%d commit behind
'
,
'
%d commits behind
'
,
this
.
mr
.
divergedCommitsCount
);
type
:
Object
,
required
:
true
,
},
},
},
computed
:
{
branchNameClipboardData
()
{
shouldShowCommitsBehindText
()
{
// This supports code in app/assets/javascripts/copy_to_clipboard.js that
return
this
.
mr
.
divergedCommitsCount
>
0
;
// works around ClipboardJS limitations to allow the context-specific
},
// copy/pasting of plain text or GFM.
commitsText
()
{
return
JSON
.
stringify
({
return
n__
(
'
%d commit behind
'
,
'
%d commits behind
'
,
this
.
mr
.
divergedCommitsCount
);
text
:
this
.
mr
.
sourceBranch
,
},
gfm
:
`\`
${
this
.
mr
.
sourceBranch
}
\``
,
branchNameClipboardData
()
{
});
// This supports code in app/assets/javascripts/copy_to_clipboard.js that
// works around ClipboardJS limitations to allow the context-specific
// copy/pasting of plain text or GFM.
return
JSON
.
stringify
({
text
:
this
.
mr
.
sourceBranch
,
gfm
:
`\`
${
this
.
mr
.
sourceBranch
}
\``
,
});
},
isSourceBranchLong
()
{
return
this
.
isBranchTitleLong
(
this
.
mr
.
sourceBranch
);
},
isTargetBranchLong
()
{
return
this
.
isBranchTitleLong
(
this
.
mr
.
targetBranch
);
},
},
},
methods
:
{
isSourceBranchLong
()
{
isBranchTitleLong
(
branchTitle
)
{
return
this
.
isBranchTitleLong
(
this
.
mr
.
sourceBranch
);
return
branchTitle
.
length
>
32
;
},
},
},
};
isTargetBranchLong
()
{
return
this
.
isBranchTitleLong
(
this
.
mr
.
targetBranch
);
},
webIdePath
()
{
return
webIDEUrl
(
this
.
mr
.
statusPath
.
replace
(
'
.json
'
,
''
));
},
},
methods
:
{
isBranchTitleLong
(
branchTitle
)
{
return
branchTitle
.
length
>
32
;
},
},
};
</
script
>
</
script
>
<
template
>
<
template
>
<div
class=
"mr-source-target"
>
<div
class=
"mr-source-target"
>
...
@@ -96,6 +100,13 @@
...
@@ -96,6 +100,13 @@
</div>
</div>
<div
v-if=
"mr.isOpen"
>
<div
v-if=
"mr.isOpen"
>
<a
v-if=
"!mr.sourceBranchRemoved"
:href=
"webIdePath"
class=
"btn btn-sm btn-default inline js-web-ide"
>
{{
s__
(
"
mrWidget|Web IDE
"
)
}}
</a>
<button
<button
data-target=
"#modal_merge_info"
data-target=
"#modal_merge_info"
data-toggle=
"modal"
data-toggle=
"modal"
...
...
app/assets/stylesheets/pages/repo.scss
View file @
4410a1fa
...
@@ -50,6 +50,7 @@
...
@@ -50,6 +50,7 @@
flex
:
1
;
flex
:
1
;
white-space
:
nowrap
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
text-overflow
:
ellipsis
;
max-width
:
inherit
;
svg
{
svg
{
vertical-align
:
middle
;
vertical-align
:
middle
;
...
@@ -720,9 +721,7 @@
...
@@ -720,9 +721,7 @@
}
}
.ide-view
{
.ide-view
{
height
:
calc
(
height
:
calc
(
100vh
-
#{
$header-height
+
$performance-bar-height
+
$flash-height
}
);
100vh
-
#{
$header-height
+
$performance-bar-height
+
$flash-height
}
);
}
}
}
}
}
}
...
...
spec/javascripts/api_spec.js
View file @
4410a1fa
This diff is collapsed.
Click to expand it.
spec/javascripts/ide/components/changed_file_icon_spec.js
View file @
4410a1fa
...
@@ -11,6 +11,7 @@ describe('IDE changed file icon', () => {
...
@@ -11,6 +11,7 @@ describe('IDE changed file icon', () => {
vm
=
createComponent
(
component
,
{
vm
=
createComponent
(
component
,
{
file
:
{
file
:
{
tempFile
:
false
,
tempFile
:
false
,
changed
:
true
,
},
},
});
});
});
});
...
@@ -20,7 +21,7 @@ describe('IDE changed file icon', () => {
...
@@ -20,7 +21,7 @@ describe('IDE changed file icon', () => {
});
});
describe
(
'
changedIcon
'
,
()
=>
{
describe
(
'
changedIcon
'
,
()
=>
{
it
(
'
equals file-modified when not a temp file
'
,
()
=>
{
it
(
'
equals file-modified when not a temp file
and has changes
'
,
()
=>
{
expect
(
vm
.
changedIcon
).
toBe
(
'
file-modified
'
);
expect
(
vm
.
changedIcon
).
toBe
(
'
file-modified
'
);
});
});
...
...
spec/javascripts/ide/components/repo_editor_spec.js
View file @
4410a1fa
...
@@ -89,6 +89,20 @@ describe('RepoEditor', () => {
...
@@ -89,6 +89,20 @@ describe('RepoEditor', () => {
done
();
done
();
});
});
});
});
it
(
'
calls createDiffInstance when viewer is a merge request diff
'
,
done
=>
{
vm
.
$store
.
state
.
viewer
=
'
mrdiff
'
;
spyOn
(
vm
.
editor
,
'
createDiffInstance
'
);
vm
.
createEditorInstance
();
vm
.
$nextTick
(()
=>
{
expect
(
vm
.
editor
.
createDiffInstance
).
toHaveBeenCalled
();
done
();
});
});
});
});
describe
(
'
setupEditor
'
,
()
=>
{
describe
(
'
setupEditor
'
,
()
=>
{
...
@@ -134,4 +148,48 @@ describe('RepoEditor', () => {
...
@@ -134,4 +148,48 @@ describe('RepoEditor', () => {
});
});
});
});
});
});
describe
(
'
setup editor for merge request viewing
'
,
()
=>
{
beforeEach
(
done
=>
{
// Resetting as the main test setup has already done it
vm
.
$destroy
();
resetStore
(
vm
.
$store
);
Editor
.
editorInstance
.
modelManager
.
dispose
();
const
f
=
{
...
file
(),
active
:
true
,
tempFile
:
true
,
html
:
'
testing
'
,
mrChange
:
{
diff
:
'
ABC
'
},
baseRaw
:
'
testing
'
,
content
:
'
test
'
,
};
const
RepoEditor
=
Vue
.
extend
(
repoEditor
);
vm
=
createComponentWithStore
(
RepoEditor
,
store
,
{
file
:
f
,
});
vm
.
$store
.
state
.
openFiles
.
push
(
f
);
vm
.
$store
.
state
.
entries
[
f
.
path
]
=
f
;
vm
.
$store
.
state
.
viewer
=
'
mrdiff
'
;
vm
.
monaco
=
true
;
vm
.
$mount
();
monacoLoader
([
'
vs/editor/editor.main
'
],
()
=>
{
setTimeout
(
done
,
0
);
});
});
it
(
'
attaches merge request model to editor when merge request diff
'
,
()
=>
{
spyOn
(
vm
.
editor
,
'
attachMergeRequestModel
'
).
and
.
callThrough
();
vm
.
setupEditor
();
expect
(
vm
.
editor
.
attachMergeRequestModel
).
toHaveBeenCalledWith
(
vm
.
model
);
});
});
});
});
spec/javascripts/ide/components/repo_tabs_spec.js
View file @
4410a1fa
...
@@ -17,6 +17,7 @@ describe('RepoTabs', () => {
...
@@ -17,6 +17,7 @@ describe('RepoTabs', () => {
files
:
openedFiles
,
files
:
openedFiles
,
viewer
:
'
editor
'
,
viewer
:
'
editor
'
,
hasChanges
:
false
,
hasChanges
:
false
,
hasMergeRequest
:
false
,
});
});
openedFiles
[
0
].
active
=
true
;
openedFiles
[
0
].
active
=
true
;
...
@@ -56,6 +57,7 @@ describe('RepoTabs', () => {
...
@@ -56,6 +57,7 @@ describe('RepoTabs', () => {
files
:
[],
files
:
[],
viewer
:
'
editor
'
,
viewer
:
'
editor
'
,
hasChanges
:
false
,
hasChanges
:
false
,
hasMergeRequest
:
false
,
},
},
'
#test-app
'
,
'
#test-app
'
,
);
);
...
...
spec/javascripts/ide/lib/common/model_spec.js
View file @
4410a1fa
...
@@ -11,7 +11,10 @@ describe('Multi-file editor library model', () => {
...
@@ -11,7 +11,10 @@ describe('Multi-file editor library model', () => {
spyOn
(
eventHub
,
'
$on
'
).
and
.
callThrough
();
spyOn
(
eventHub
,
'
$on
'
).
and
.
callThrough
();
monacoLoader
([
'
vs/editor/editor.main
'
],
()
=>
{
monacoLoader
([
'
vs/editor/editor.main
'
],
()
=>
{
model
=
new
Model
(
monaco
,
file
(
'
path
'
));
const
f
=
file
(
'
path
'
);
f
.
mrChange
=
{
diff
:
'
ABC
'
};
f
.
baseRaw
=
'
test
'
;
model
=
new
Model
(
monaco
,
f
);
done
();
done
();
});
});
...
@@ -21,9 +24,10 @@ describe('Multi-file editor library model', () => {
...
@@ -21,9 +24,10 @@ describe('Multi-file editor library model', () => {
model
.
dispose
();
model
.
dispose
();
});
});
it
(
'
creates original model & new model
'
,
()
=>
{
it
(
'
creates original model &
base model &
new model
'
,
()
=>
{
expect
(
model
.
originalModel
).
not
.
toBeNull
();
expect
(
model
.
originalModel
).
not
.
toBeNull
();
expect
(
model
.
model
).
not
.
toBeNull
();
expect
(
model
.
model
).
not
.
toBeNull
();
expect
(
model
.
baseModel
).
not
.
toBeNull
();
});
});
it
(
'
adds eventHub listener
'
,
()
=>
{
it
(
'
adds eventHub listener
'
,
()
=>
{
...
@@ -51,6 +55,12 @@ describe('Multi-file editor library model', () => {
...
@@ -51,6 +55,12 @@ describe('Multi-file editor library model', () => {
});
});
});
});
describe
(
'
getBaseModel
'
,
()
=>
{
it
(
'
returns base model
'
,
()
=>
{
expect
(
model
.
getBaseModel
()).
toBe
(
model
.
baseModel
);
});
});
describe
(
'
setValue
'
,
()
=>
{
describe
(
'
setValue
'
,
()
=>
{
it
(
'
updates models value
'
,
()
=>
{
it
(
'
updates models value
'
,
()
=>
{
model
.
setValue
(
'
testing 123
'
);
model
.
setValue
(
'
testing 123
'
);
...
...
spec/javascripts/ide/lib/editor_spec.js
View file @
4410a1fa
...
@@ -151,6 +151,31 @@ describe('Multi-file editor library', () => {
...
@@ -151,6 +151,31 @@ describe('Multi-file editor library', () => {
});
});
});
});
describe
(
'
attachMergeRequestModel
'
,
()
=>
{
let
model
;
beforeEach
(()
=>
{
instance
.
createDiffInstance
(
document
.
createElement
(
'
div
'
));
const
f
=
file
();
f
.
mrChanges
=
{
diff
:
'
ABC
'
};
f
.
baseRaw
=
'
testing
'
;
model
=
instance
.
createModel
(
f
);
});
it
(
'
sets original & modified
'
,
()
=>
{
spyOn
(
instance
.
instance
,
'
setModel
'
);
instance
.
attachMergeRequestModel
(
model
);
expect
(
instance
.
instance
.
setModel
).
toHaveBeenCalledWith
({
original
:
model
.
getBaseModel
(),
modified
:
model
.
getModel
(),
});
});
});
describe
(
'
clearEditor
'
,
()
=>
{
describe
(
'
clearEditor
'
,
()
=>
{
it
(
'
resets the editor model
'
,
()
=>
{
it
(
'
resets the editor model
'
,
()
=>
{
instance
.
createInstance
(
document
.
createElement
(
'
div
'
));
instance
.
createInstance
(
document
.
createElement
(
'
div
'
));
...
...
spec/javascripts/ide/stores/actions/file_spec.js
View file @
4410a1fa
...
@@ -5,7 +5,7 @@ import router from '~/ide/ide_router';
...
@@ -5,7 +5,7 @@ import router from '~/ide/ide_router';
import
eventHub
from
'
~/ide/eventhub
'
;
import
eventHub
from
'
~/ide/eventhub
'
;
import
{
file
,
resetStore
}
from
'
../../helpers
'
;
import
{
file
,
resetStore
}
from
'
../../helpers
'
;
describe
(
'
Multi-file
store file actions
'
,
()
=>
{
describe
(
'
IDE
store file actions
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
spyOn
(
router
,
'
push
'
);
spyOn
(
router
,
'
push
'
);
});
});
...
@@ -189,7 +189,7 @@ describe('Multi-file store file actions', () => {
...
@@ -189,7 +189,7 @@ describe('Multi-file store file actions', () => {
it
(
'
calls the service
'
,
done
=>
{
it
(
'
calls the service
'
,
done
=>
{
store
store
.
dispatch
(
'
getFileData
'
,
localFile
)
.
dispatch
(
'
getFileData
'
,
{
path
:
localFile
.
path
}
)
.
then
(()
=>
{
.
then
(()
=>
{
expect
(
service
.
getFileData
).
toHaveBeenCalledWith
(
'
getFileDataURL
'
);
expect
(
service
.
getFileData
).
toHaveBeenCalledWith
(
'
getFileDataURL
'
);
...
@@ -200,7 +200,7 @@ describe('Multi-file store file actions', () => {
...
@@ -200,7 +200,7 @@ describe('Multi-file store file actions', () => {
it
(
'
sets the file data
'
,
done
=>
{
it
(
'
sets the file data
'
,
done
=>
{
store
store
.
dispatch
(
'
getFileData
'
,
localFile
)
.
dispatch
(
'
getFileData
'
,
{
path
:
localFile
.
path
}
)
.
then
(()
=>
{
.
then
(()
=>
{
expect
(
localFile
.
blamePath
).
toBe
(
'
blame_path
'
);
expect
(
localFile
.
blamePath
).
toBe
(
'
blame_path
'
);
...
@@ -211,7 +211,7 @@ describe('Multi-file store file actions', () => {
...
@@ -211,7 +211,7 @@ describe('Multi-file store file actions', () => {
it
(
'
sets document title
'
,
done
=>
{
it
(
'
sets document title
'
,
done
=>
{
store
store
.
dispatch
(
'
getFileData
'
,
localFile
)
.
dispatch
(
'
getFileData
'
,
{
path
:
localFile
.
path
}
)
.
then
(()
=>
{
.
then
(()
=>
{
expect
(
document
.
title
).
toBe
(
'
testing getFileData
'
);
expect
(
document
.
title
).
toBe
(
'
testing getFileData
'
);
...
@@ -222,7 +222,7 @@ describe('Multi-file store file actions', () => {
...
@@ -222,7 +222,7 @@ describe('Multi-file store file actions', () => {
it
(
'
sets the file as active
'
,
done
=>
{
it
(
'
sets the file as active
'
,
done
=>
{
store
store
.
dispatch
(
'
getFileData
'
,
localFile
)
.
dispatch
(
'
getFileData
'
,
{
path
:
localFile
.
path
}
)
.
then
(()
=>
{
.
then
(()
=>
{
expect
(
localFile
.
active
).
toBeTruthy
();
expect
(
localFile
.
active
).
toBeTruthy
();
...
@@ -231,9 +231,20 @@ describe('Multi-file store file actions', () => {
...
@@ -231,9 +231,20 @@ describe('Multi-file store file actions', () => {
.
catch
(
done
.
fail
);
.
catch
(
done
.
fail
);
});
});
it
(
'
sets the file not as active if we pass makeFileActive false
'
,
done
=>
{
store
.
dispatch
(
'
getFileData
'
,
{
path
:
localFile
.
path
,
makeFileActive
:
false
})
.
then
(()
=>
{
expect
(
localFile
.
active
).
toBeFalsy
();
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
adds the file to open files
'
,
done
=>
{
it
(
'
adds the file to open files
'
,
done
=>
{
store
store
.
dispatch
(
'
getFileData
'
,
localFile
)
.
dispatch
(
'
getFileData
'
,
{
path
:
localFile
.
path
}
)
.
then
(()
=>
{
.
then
(()
=>
{
expect
(
store
.
state
.
openFiles
.
length
).
toBe
(
1
);
expect
(
store
.
state
.
openFiles
.
length
).
toBe
(
1
);
expect
(
store
.
state
.
openFiles
[
0
].
name
).
toBe
(
localFile
.
name
);
expect
(
store
.
state
.
openFiles
[
0
].
name
).
toBe
(
localFile
.
name
);
...
@@ -256,7 +267,7 @@ describe('Multi-file store file actions', () => {
...
@@ -256,7 +267,7 @@ describe('Multi-file store file actions', () => {
it
(
'
calls getRawFileData service method
'
,
done
=>
{
it
(
'
calls getRawFileData service method
'
,
done
=>
{
store
store
.
dispatch
(
'
getRawFileData
'
,
tmpFile
)
.
dispatch
(
'
getRawFileData
'
,
{
path
:
tmpFile
.
path
}
)
.
then
(()
=>
{
.
then
(()
=>
{
expect
(
service
.
getRawFileData
).
toHaveBeenCalledWith
(
tmpFile
);
expect
(
service
.
getRawFileData
).
toHaveBeenCalledWith
(
tmpFile
);
...
@@ -267,7 +278,7 @@ describe('Multi-file store file actions', () => {
...
@@ -267,7 +278,7 @@ describe('Multi-file store file actions', () => {
it
(
'
updates file raw data
'
,
done
=>
{
it
(
'
updates file raw data
'
,
done
=>
{
store
store
.
dispatch
(
'
getRawFileData
'
,
tmpFile
)
.
dispatch
(
'
getRawFileData
'
,
{
path
:
tmpFile
.
path
}
)
.
then
(()
=>
{
.
then
(()
=>
{
expect
(
tmpFile
.
raw
).
toBe
(
'
raw
'
);
expect
(
tmpFile
.
raw
).
toBe
(
'
raw
'
);
...
@@ -275,6 +286,22 @@ describe('Multi-file store file actions', () => {
...
@@ -275,6 +286,22 @@ describe('Multi-file store file actions', () => {
})
})
.
catch
(
done
.
fail
);
.
catch
(
done
.
fail
);
});
});
it
(
'
calls also getBaseRawFileData service method
'
,
done
=>
{
spyOn
(
service
,
'
getBaseRawFileData
'
).
and
.
returnValue
(
Promise
.
resolve
(
'
baseraw
'
));
tmpFile
.
mrChange
=
{
new_file
:
false
};
store
.
dispatch
(
'
getRawFileData
'
,
{
path
:
tmpFile
.
path
,
baseSha
:
'
SHA
'
})
.
then
(()
=>
{
expect
(
service
.
getBaseRawFileData
).
toHaveBeenCalledWith
(
tmpFile
,
'
SHA
'
);
expect
(
tmpFile
.
baseRaw
).
toBe
(
'
baseraw
'
);
done
();
})
.
catch
(
done
.
fail
);
});
});
});
describe
(
'
changeFileContent
'
,
()
=>
{
describe
(
'
changeFileContent
'
,
()
=>
{
...
...
spec/javascripts/ide/stores/actions/merge_request_spec.js
0 → 100644
View file @
4410a1fa
import
store
from
'
~/ide/stores
'
;
import
service
from
'
~/ide/services
'
;
import
{
resetStore
}
from
'
../../helpers
'
;
describe
(
'
IDE store merge request actions
'
,
()
=>
{
beforeEach
(()
=>
{
store
.
state
.
projects
.
abcproject
=
{
mergeRequests
:
{},
};
});
afterEach
(()
=>
{
resetStore
(
store
);
});
describe
(
'
getMergeRequestData
'
,
()
=>
{
beforeEach
(()
=>
{
spyOn
(
service
,
'
getProjectMergeRequestData
'
).
and
.
returnValue
(
Promise
.
resolve
({
data
:
{
title
:
'
mergerequest
'
}
}),
);
});
it
(
'
calls getProjectMergeRequestData service method
'
,
done
=>
{
store
.
dispatch
(
'
getMergeRequestData
'
,
{
projectId
:
'
abcproject
'
,
mergeRequestId
:
1
})
.
then
(()
=>
{
expect
(
service
.
getProjectMergeRequestData
).
toHaveBeenCalledWith
(
'
abcproject
'
,
1
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
sets the Merge Request Object
'
,
done
=>
{
store
.
dispatch
(
'
getMergeRequestData
'
,
{
projectId
:
'
abcproject
'
,
mergeRequestId
:
1
})
.
then
(()
=>
{
expect
(
store
.
state
.
projects
.
abcproject
.
mergeRequests
[
'
1
'
].
title
).
toBe
(
'
mergerequest
'
);
expect
(
store
.
state
.
currentMergeRequestId
).
toBe
(
1
);
done
();
})
.
catch
(
done
.
fail
);
});
});
describe
(
'
getMergeRequestChanges
'
,
()
=>
{
beforeEach
(()
=>
{
spyOn
(
service
,
'
getProjectMergeRequestChanges
'
).
and
.
returnValue
(
Promise
.
resolve
({
data
:
{
title
:
'
mergerequest
'
}
}),
);
store
.
state
.
projects
.
abcproject
.
mergeRequests
[
'
1
'
]
=
{
changes
:
[]
};
});
it
(
'
calls getProjectMergeRequestChanges service method
'
,
done
=>
{
store
.
dispatch
(
'
getMergeRequestChanges
'
,
{
projectId
:
'
abcproject
'
,
mergeRequestId
:
1
})
.
then
(()
=>
{
expect
(
service
.
getProjectMergeRequestChanges
).
toHaveBeenCalledWith
(
'
abcproject
'
,
1
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
sets the Merge Request Changes Object
'
,
done
=>
{
store
.
dispatch
(
'
getMergeRequestChanges
'
,
{
projectId
:
'
abcproject
'
,
mergeRequestId
:
1
})
.
then
(()
=>
{
expect
(
store
.
state
.
projects
.
abcproject
.
mergeRequests
[
'
1
'
].
changes
.
title
).
toBe
(
'
mergerequest
'
,
);
done
();
})
.
catch
(
done
.
fail
);
});
});
describe
(
'
getMergeRequestVersions
'
,
()
=>
{
beforeEach
(()
=>
{
spyOn
(
service
,
'
getProjectMergeRequestVersions
'
).
and
.
returnValue
(
Promise
.
resolve
({
data
:
[{
id
:
789
}]
}),
);
store
.
state
.
projects
.
abcproject
.
mergeRequests
[
'
1
'
]
=
{
versions
:
[]
};
});
it
(
'
calls getProjectMergeRequestVersions service method
'
,
done
=>
{
store
.
dispatch
(
'
getMergeRequestVersions
'
,
{
projectId
:
'
abcproject
'
,
mergeRequestId
:
1
})
.
then
(()
=>
{
expect
(
service
.
getProjectMergeRequestVersions
).
toHaveBeenCalledWith
(
'
abcproject
'
,
1
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
sets the Merge Request Versions Object
'
,
done
=>
{
store
.
dispatch
(
'
getMergeRequestVersions
'
,
{
projectId
:
'
abcproject
'
,
mergeRequestId
:
1
})
.
then
(()
=>
{
expect
(
store
.
state
.
projects
.
abcproject
.
mergeRequests
[
'
1
'
].
versions
.
length
).
toBe
(
1
);
done
();
})
.
catch
(
done
.
fail
);
});
});
});
spec/javascripts/ide/stores/actions/tree_spec.js
View file @
4410a1fa
...
@@ -68,9 +68,7 @@ describe('Multi-file store tree actions', () => {
...
@@ -68,9 +68,7 @@ describe('Multi-file store tree actions', () => {
expect
(
projectTree
.
tree
[
0
].
tree
[
1
].
name
).
toBe
(
'
fileinfolder.js
'
);
expect
(
projectTree
.
tree
[
0
].
tree
[
1
].
name
).
toBe
(
'
fileinfolder.js
'
);
expect
(
projectTree
.
tree
[
1
].
type
).
toBe
(
'
blob
'
);
expect
(
projectTree
.
tree
[
1
].
type
).
toBe
(
'
blob
'
);
expect
(
projectTree
.
tree
[
0
].
tree
[
0
].
tree
[
0
].
type
).
toBe
(
'
blob
'
);
expect
(
projectTree
.
tree
[
0
].
tree
[
0
].
tree
[
0
].
type
).
toBe
(
'
blob
'
);
expect
(
projectTree
.
tree
[
0
].
tree
[
0
].
tree
[
0
].
name
).
toBe
(
expect
(
projectTree
.
tree
[
0
].
tree
[
0
].
tree
[
0
].
name
).
toBe
(
'
fileinsubfolder.js
'
);
'
fileinsubfolder.js
'
,
);
done
();
done
();
})
})
...
@@ -132,9 +130,7 @@ describe('Multi-file store tree actions', () => {
...
@@ -132,9 +130,7 @@ describe('Multi-file store tree actions', () => {
store
store
.
dispatch
(
'
getLastCommitData
'
,
projectTree
)
.
dispatch
(
'
getLastCommitData
'
,
projectTree
)
.
then
(()
=>
{
.
then
(()
=>
{
expect
(
service
.
getTreeLastCommit
).
toHaveBeenCalledWith
(
expect
(
service
.
getTreeLastCommit
).
toHaveBeenCalledWith
(
'
lastcommitpath
'
);
'
lastcommitpath
'
,
);
done
();
done
();
})
})
...
@@ -160,9 +156,7 @@ describe('Multi-file store tree actions', () => {
...
@@ -160,9 +156,7 @@ describe('Multi-file store tree actions', () => {
.
dispatch
(
'
getLastCommitData
'
,
projectTree
)
.
dispatch
(
'
getLastCommitData
'
,
projectTree
)
.
then
(
Vue
.
nextTick
)
.
then
(
Vue
.
nextTick
)
.
then
(()
=>
{
.
then
(()
=>
{
expect
(
projectTree
.
tree
[
0
].
lastCommit
.
message
).
not
.
toBe
(
expect
(
projectTree
.
tree
[
0
].
lastCommit
.
message
).
not
.
toBe
(
'
commit message
'
);
'
commit message
'
,
);
done
();
done
();
})
})
...
...
spec/javascripts/ide/stores/getters_spec.js
View file @
4410a1fa
...
@@ -2,7 +2,7 @@ import * as getters from '~/ide/stores/getters';
...
@@ -2,7 +2,7 @@ import * as getters from '~/ide/stores/getters';
import
state
from
'
~/ide/stores/state
'
;
import
state
from
'
~/ide/stores/state
'
;
import
{
file
}
from
'
../helpers
'
;
import
{
file
}
from
'
../helpers
'
;
describe
(
'
Multi-file
store getters
'
,
()
=>
{
describe
(
'
IDE
store getters
'
,
()
=>
{
let
localState
;
let
localState
;
beforeEach
(()
=>
{
beforeEach
(()
=>
{
...
@@ -52,4 +52,24 @@ describe('Multi-file store getters', () => {
...
@@ -52,4 +52,24 @@ describe('Multi-file store getters', () => {
expect
(
modifiedFiles
[
0
].
name
).
toBe
(
'
added
'
);
expect
(
modifiedFiles
[
0
].
name
).
toBe
(
'
added
'
);
});
});
});
});
describe
(
'
currentMergeRequest
'
,
()
=>
{
it
(
'
returns Current Merge Request
'
,
()
=>
{
localState
.
currentProjectId
=
'
abcproject
'
;
localState
.
currentMergeRequestId
=
1
;
localState
.
projects
.
abcproject
=
{
mergeRequests
:
{
1
:
{
mergeId
:
1
},
},
};
expect
(
getters
.
currentMergeRequest
(
localState
).
mergeId
).
toBe
(
1
);
});
it
(
'
returns null if no active Merge Request was found
'
,
()
=>
{
localState
.
currentProjectId
=
'
otherproject
'
;
expect
(
getters
.
currentMergeRequest
(
localState
)).
toBeNull
();
});
});
});
});
spec/javascripts/ide/stores/mutations/file_spec.js
View file @
4410a1fa
...
@@ -2,7 +2,7 @@ import mutations from '~/ide/stores/mutations/file';
...
@@ -2,7 +2,7 @@ import mutations from '~/ide/stores/mutations/file';
import
state
from
'
~/ide/stores/state
'
;
import
state
from
'
~/ide/stores/state
'
;
import
{
file
}
from
'
../../helpers
'
;
import
{
file
}
from
'
../../helpers
'
;
describe
(
'
Multi-file
store file mutations
'
,
()
=>
{
describe
(
'
IDE
store file mutations
'
,
()
=>
{
let
localState
;
let
localState
;
let
localFile
;
let
localFile
;
...
@@ -62,6 +62,8 @@ describe('Multi-file store file mutations', () => {
...
@@ -62,6 +62,8 @@ describe('Multi-file store file mutations', () => {
expect
(
localFile
.
rawPath
).
toBe
(
'
raw
'
);
expect
(
localFile
.
rawPath
).
toBe
(
'
raw
'
);
expect
(
localFile
.
binary
).
toBeTruthy
();
expect
(
localFile
.
binary
).
toBeTruthy
();
expect
(
localFile
.
renderError
).
toBe
(
'
render_error
'
);
expect
(
localFile
.
renderError
).
toBe
(
'
render_error
'
);
expect
(
localFile
.
raw
).
toBeNull
();
expect
(
localFile
.
baseRaw
).
toBeNull
();
});
});
});
});
...
@@ -76,6 +78,17 @@ describe('Multi-file store file mutations', () => {
...
@@ -76,6 +78,17 @@ describe('Multi-file store file mutations', () => {
});
});
});
});
describe
(
'
SET_FILE_BASE_RAW_DATA
'
,
()
=>
{
it
(
'
sets raw data from base branch
'
,
()
=>
{
mutations
.
SET_FILE_BASE_RAW_DATA
(
localState
,
{
file
:
localFile
,
baseRaw
:
'
testing
'
,
});
expect
(
localFile
.
baseRaw
).
toBe
(
'
testing
'
);
});
});
describe
(
'
UPDATE_FILE_CONTENT
'
,
()
=>
{
describe
(
'
UPDATE_FILE_CONTENT
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
localFile
.
raw
=
'
test
'
;
localFile
.
raw
=
'
test
'
;
...
@@ -112,6 +125,17 @@ describe('Multi-file store file mutations', () => {
...
@@ -112,6 +125,17 @@ describe('Multi-file store file mutations', () => {
});
});
});
});
describe
(
'
SET_FILE_MERGE_REQUEST_CHANGE
'
,
()
=>
{
it
(
'
sets file mr change
'
,
()
=>
{
mutations
.
SET_FILE_MERGE_REQUEST_CHANGE
(
localState
,
{
file
:
localFile
,
mrChange
:
{
diff
:
'
ABC
'
},
});
expect
(
localFile
.
mrChange
.
diff
).
toBe
(
'
ABC
'
);
});
});
describe
(
'
DISCARD_FILE_CHANGES
'
,
()
=>
{
describe
(
'
DISCARD_FILE_CHANGES
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
localFile
.
content
=
'
test
'
;
localFile
.
content
=
'
test
'
;
...
...
spec/javascripts/ide/stores/mutations/merge_request_spec.js
0 → 100644
View file @
4410a1fa
import
mutations
from
'
~/ide/stores/mutations/merge_request
'
;
import
state
from
'
~/ide/stores/state
'
;
describe
(
'
IDE store merge request mutations
'
,
()
=>
{
let
localState
;
beforeEach
(()
=>
{
localState
=
state
();
localState
.
projects
=
{
abcproject
:
{
mergeRequests
:
{}
}
};
mutations
.
SET_MERGE_REQUEST
(
localState
,
{
projectPath
:
'
abcproject
'
,
mergeRequestId
:
1
,
mergeRequest
:
{
title
:
'
mr
'
,
},
});
});
describe
(
'
SET_CURRENT_MERGE_REQUEST
'
,
()
=>
{
it
(
'
sets current merge request
'
,
()
=>
{
mutations
.
SET_CURRENT_MERGE_REQUEST
(
localState
,
2
);
expect
(
localState
.
currentMergeRequestId
).
toBe
(
2
);
});
});
describe
(
'
SET_MERGE_REQUEST
'
,
()
=>
{
it
(
'
setsmerge request data
'
,
()
=>
{
const
newMr
=
localState
.
projects
.
abcproject
.
mergeRequests
[
1
];
expect
(
newMr
.
title
).
toBe
(
'
mr
'
);
expect
(
newMr
.
active
).
toBeTruthy
();
});
});
describe
(
'
SET_MERGE_REQUEST_CHANGES
'
,
()
=>
{
it
(
'
sets merge request changes
'
,
()
=>
{
mutations
.
SET_MERGE_REQUEST_CHANGES
(
localState
,
{
projectPath
:
'
abcproject
'
,
mergeRequestId
:
1
,
changes
:
{
diff
:
'
abc
'
,
},
});
const
newMr
=
localState
.
projects
.
abcproject
.
mergeRequests
[
1
];
expect
(
newMr
.
changes
.
diff
).
toBe
(
'
abc
'
);
});
});
describe
(
'
SET_MERGE_REQUEST_VERSIONS
'
,
()
=>
{
it
(
'
sets merge request versions
'
,
()
=>
{
mutations
.
SET_MERGE_REQUEST_VERSIONS
(
localState
,
{
projectPath
:
'
abcproject
'
,
mergeRequestId
:
1
,
versions
:
[{
id
:
123
}],
});
const
newMr
=
localState
.
projects
.
abcproject
.
mergeRequests
[
1
];
expect
(
newMr
.
versions
.
length
).
toBe
(
1
);
expect
(
newMr
.
versions
[
0
].
id
).
toBe
(
123
);
});
});
});
spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js
View file @
4410a1fa
This diff is collapsed.
Click to expand it.
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