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
cded268c
Commit
cded268c
authored
Jul 26, 2018
by
Phil Hughes
Committed by
Tim Zallmann
Jul 26, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Enable deleting files in the Web IDE
parent
88738408
Changes
36
Show whitespace changes
Inline
Side-by-side
Showing
36 changed files
with
545 additions
and
116 deletions
+545
-116
app/assets/javascripts/ide/components/changed_file_icon.vue
app/assets/javascripts/ide/components/changed_file_icon.vue
+11
-9
app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
...s/javascripts/ide/components/commit_sidebar/list_item.vue
+7
-3
app/assets/javascripts/ide/components/ide_review.vue
app/assets/javascripts/ide/components/ide_review.vue
+10
-3
app/assets/javascripts/ide/components/ide_tree.vue
app/assets/javascripts/ide/components/ide_tree.vue
+6
-2
app/assets/javascripts/ide/components/ide_tree_list.vue
app/assets/javascripts/ide/components/ide_tree_list.vue
+0
-6
app/assets/javascripts/ide/components/new_dropdown/index.vue
app/assets/javascripts/ide/components/new_dropdown/index.vue
+32
-20
app/assets/javascripts/ide/components/repo_commit_section.vue
...assets/javascripts/ide/components/repo_commit_section.vue
+1
-1
app/assets/javascripts/ide/components/repo_editor.vue
app/assets/javascripts/ide/components/repo_editor.vue
+14
-3
app/assets/javascripts/ide/components/repo_file.vue
app/assets/javascripts/ide/components/repo_file.vue
+1
-7
app/assets/javascripts/ide/components/repo_tab.vue
app/assets/javascripts/ide/components/repo_tab.vue
+3
-3
app/assets/javascripts/ide/constants.js
app/assets/javascripts/ide/constants.js
+15
-0
app/assets/javascripts/ide/lib/common/model.js
app/assets/javascripts/ide/lib/common/model.js
+1
-1
app/assets/javascripts/ide/stores/actions.js
app/assets/javascripts/ide/stores/actions.js
+8
-0
app/assets/javascripts/ide/stores/actions/file.js
app/assets/javascripts/ide/stores/actions/file.js
+6
-2
app/assets/javascripts/ide/stores/actions/tree.js
app/assets/javascripts/ide/stores/actions/tree.js
+2
-4
app/assets/javascripts/ide/stores/modules/commit/actions.js
app/assets/javascripts/ide/stores/modules/commit/actions.js
+7
-5
app/assets/javascripts/ide/stores/modules/commit/getters.js
app/assets/javascripts/ide/stores/modules/commit/getters.js
+18
-8
app/assets/javascripts/ide/stores/mutation_types.js
app/assets/javascripts/ide/stores/mutation_types.js
+1
-0
app/assets/javascripts/ide/stores/mutations.js
app/assets/javascripts/ide/stores/mutations.js
+11
-0
app/assets/javascripts/ide/stores/mutations/file.js
app/assets/javascripts/ide/stores/mutations/file.js
+20
-0
app/assets/javascripts/ide/stores/utils.js
app/assets/javascripts/ide/stores/utils.js
+26
-3
app/assets/javascripts/ide/utils.js
app/assets/javascripts/ide/utils.js
+12
-0
app/assets/stylesheets/page_bundles/ide.scss
app/assets/stylesheets/page_bundles/ide.scss
+58
-5
changelogs/unreleased/ide-delete-entries.yml
changelogs/unreleased/ide-delete-entries.yml
+5
-0
locale/gitlab.pot
locale/gitlab.pot
+10
-4
spec/javascripts/ide/components/changed_file_icon_spec.js
spec/javascripts/ide/components/changed_file_icon_spec.js
+4
-4
spec/javascripts/ide/components/commit_sidebar/list_item_spec.js
...vascripts/ide/components/commit_sidebar/list_item_spec.js
+14
-2
spec/javascripts/ide/components/new_dropdown/index_spec.js
spec/javascripts/ide/components/new_dropdown/index_spec.js
+11
-0
spec/javascripts/ide/components/repo_editor_spec.js
spec/javascripts/ide/components/repo_editor_spec.js
+3
-0
spec/javascripts/ide/components/repo_file_spec.js
spec/javascripts/ide/components/repo_file_spec.js
+0
-19
spec/javascripts/ide/components/repo_tab_spec.js
spec/javascripts/ide/components/repo_tab_spec.js
+2
-2
spec/javascripts/ide/stores/actions_spec.js
spec/javascripts/ide/stores/actions_spec.js
+16
-0
spec/javascripts/ide/stores/modules/commit/getters_spec.js
spec/javascripts/ide/stores/modules/commit/getters_spec.js
+16
-0
spec/javascripts/ide/stores/mutations/file_spec.js
spec/javascripts/ide/stores/mutations/file_spec.js
+64
-0
spec/javascripts/ide/stores/mutations_spec.js
spec/javascripts/ide/stores/mutations_spec.js
+57
-0
spec/javascripts/ide/stores/utils_spec.js
spec/javascripts/ide/stores/utils_spec.js
+73
-0
No files found.
app/assets/javascripts/ide/components/changed_file_icon.vue
View file @
cded268c
...
...
@@ -3,6 +3,7 @@ import tooltip from '~/vue_shared/directives/tooltip';
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
{
pluralize
}
from
'
~/lib/utils/text_utility
'
;
import
{
__
,
sprintf
}
from
'
~/locale
'
;
import
{
getCommitIconMap
}
from
'
../utils
'
;
export
default
{
components
:
{
...
...
@@ -34,16 +35,14 @@ export default {
},
computed
:
{
changedIcon
()
{
const
suffix
=
this
.
file
.
staged
&&
!
this
.
showStagedIcon
?
'
-solid
'
:
''
;
return
this
.
file
.
tempFile
&&
!
this
.
forceModifiedIcon
?
`file-addition
${
suffix
}
`
:
`file-modified
${
suffix
}
`
;
},
stagedIcon
()
{
return
`
${
this
.
changedIcon
}
-solid`
;
const
suffix
=
!
this
.
file
.
changed
&&
this
.
file
.
staged
&&
!
this
.
showStagedIcon
?
'
-solid
'
:
''
;
if
(
this
.
forceModifiedIcon
)
return
`file-modified
${
suffix
}
`
;
return
`
${
getCommitIconMap
(
this
.
file
).
icon
}${
suffix
}
`
;
},
changedIconClass
()
{
return
`
multi
-
${
this
.
changedIcon
}
float-left`
;
return
`
ide
-
${
this
.
changedIcon
}
float-left`
;
},
tooltipTitle
()
{
if
(
!
this
.
showTooltip
)
return
undefined
;
...
...
@@ -66,6 +65,9 @@ export default {
return
undefined
;
},
showIcon
()
{
return
this
.
file
.
changed
||
this
.
file
.
tempFile
||
this
.
file
.
staged
||
this
.
file
.
deleted
;
},
},
};
</
script
>
...
...
@@ -79,7 +81,7 @@ export default {
class=
"ide-file-changed-icon"
>
<icon
v-if=
"
file.changed || file.tempFile || file.staged
"
v-if=
"
showIcon
"
:name=
"changedIcon"
:size=
"12"
:css-classes=
"changedIconClass"
...
...
app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
View file @
cded268c
...
...
@@ -5,6 +5,7 @@ import Icon from '~/vue_shared/components/icon.vue';
import
StageButton
from
'
./stage_button.vue
'
;
import
UnstageButton
from
'
./unstage_button.vue
'
;
import
{
viewerTypes
}
from
'
../../constants
'
;
import
{
getCommitIconMap
}
from
'
../../utils
'
;
export
default
{
components
:
{
...
...
@@ -42,11 +43,12 @@ export default {
},
computed
:
{
iconName
()
{
const
prefix
=
this
.
stagedList
?
'
-solid
'
:
''
;
return
this
.
file
.
tempFile
?
`file-addition
${
prefix
}
`
:
`file-modified
${
prefix
}
`
;
const
suffix
=
this
.
stagedList
?
'
-solid
'
:
''
;
return
`
${
getCommitIconMap
(
this
.
file
).
icon
}${
suffix
}
`
;
},
iconClass
()
{
return
`
multi-file-
${
this
.
file
.
tempFile
?
'
addition
'
:
'
modified
'
}
append-right-8`
;
return
`
${
getCommitIconMap
(
this
.
file
).
class
}
append-right-8`
;
},
fullKey
()
{
return
`
${
this
.
keyPrefix
}
-
${
this
.
file
.
key
}
`
;
...
...
@@ -67,6 +69,8 @@ export default {
'
stageChange
'
,
]),
openFileInEditor
()
{
if
(
this
.
file
.
type
===
'
tree
'
)
return
null
;
return
this
.
openPendingTab
({
file
:
this
.
file
,
keyPrefix
:
this
.
keyPrefix
,
...
...
app/assets/javascripts/ide/components/ide_review.vue
View file @
cded268c
...
...
@@ -10,7 +10,7 @@ export default {
EditorModeDropdown
,
},
computed
:
{
...
mapGetters
([
'
currentMergeRequest
'
]),
...
mapGetters
([
'
currentMergeRequest
'
,
'
activeFile
'
]),
...
mapState
([
'
viewer
'
,
'
currentMergeRequestId
'
]),
showLatestChangesText
()
{
return
!
this
.
currentMergeRequestId
||
this
.
viewer
===
viewerTypes
.
diff
;
...
...
@@ -23,12 +23,20 @@ export default {
},
},
mounted
()
{
if
(
this
.
activeFile
&&
this
.
activeFile
.
pending
&&
!
this
.
activeFile
.
deleted
)
{
this
.
$router
.
push
(
`/project
${
this
.
activeFile
.
url
}
`
,
()
=>
{
this
.
updateViewer
(
'
editor
'
);
});
}
else
if
(
this
.
activeFile
&&
this
.
activeFile
.
deleted
)
{
this
.
resetOpenFiles
();
}
this
.
$nextTick
(()
=>
{
this
.
updateViewer
(
this
.
currentMergeRequestId
?
viewerTypes
.
mr
:
viewerTypes
.
diff
);
});
},
methods
:
{
...
mapActions
([
'
updateViewer
'
]),
...
mapActions
([
'
updateViewer
'
,
'
resetOpenFiles
'
]),
},
};
</
script
>
...
...
@@ -36,7 +44,6 @@ export default {
<
template
>
<ide-tree-list
:viewer-type=
"viewer"
:disable-action-dropdown=
"true"
header-class=
"ide-review-header"
>
<template
...
...
app/assets/javascripts/ide/components/ide_tree.vue
View file @
cded268c
...
...
@@ -17,14 +17,18 @@ export default {
...
mapGetters
([
'
currentProject
'
,
'
currentTree
'
,
'
activeFile
'
]),
},
mounted
()
{
if
(
this
.
activeFile
&&
this
.
activeFile
.
pending
)
{
if
(
!
this
.
activeFile
)
return
;
if
(
this
.
activeFile
.
pending
&&
!
this
.
activeFile
.
deleted
)
{
this
.
$router
.
push
(
`/project
${
this
.
activeFile
.
url
}
`
,
()
=>
{
this
.
updateViewer
(
'
editor
'
);
});
}
else
if
(
this
.
activeFile
.
deleted
)
{
this
.
resetOpenFiles
();
}
},
methods
:
{
...
mapActions
([
'
updateViewer
'
,
'
openNewEntryModal
'
,
'
createTempEntry
'
]),
...
mapActions
([
'
updateViewer
'
,
'
openNewEntryModal
'
,
'
createTempEntry
'
,
'
resetOpenFiles
'
]),
},
};
</
script
>
...
...
app/assets/javascripts/ide/components/ide_tree_list.vue
View file @
cded268c
...
...
@@ -22,11 +22,6 @@ export default {
required
:
false
,
default
:
null
,
},
disableActionDropdown
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
computed
:
{
...
mapState
([
'
currentBranchId
'
]),
...
...
@@ -69,7 +64,6 @@ export default {
:key=
"file.key"
:file=
"file"
:level=
"0"
:disable-action-dropdown=
"disableActionDropdown"
/>
</
template
>
</div>
...
...
app/assets/javascripts/ide/components/new_dropdown/index.vue
View file @
cded268c
...
...
@@ -13,7 +13,7 @@ export default {
ItemButton
,
},
props
:
{
branch
:
{
type
:
{
type
:
String
,
required
:
true
,
},
...
...
@@ -45,7 +45,7 @@ export default {
},
},
methods
:
{
...
mapActions
([
'
createTempEntry
'
,
'
openNewEntryModal
'
]),
...
mapActions
([
'
createTempEntry
'
,
'
openNewEntryModal
'
,
'
deleteEntry
'
]),
createNewItem
(
type
)
{
this
.
openNewEntryModal
({
type
,
path
:
this
.
path
});
this
.
dropdownOpen
=
false
;
...
...
@@ -82,6 +82,7 @@ export default {
ref=
"dropdownMenu"
class=
"dropdown-menu dropdown-menu-right"
>
<template
v-if=
"type === 'tree'"
>
<li>
<item-button
:label=
"__('New file')"
...
...
@@ -106,6 +107,17 @@ export default {
@
click=
"createNewItem('tree')"
/>
</li>
<li
class=
"divider"
></li>
</
template
>
<li>
<item-button
:label=
"__('Delete')"
class=
"d-flex"
icon=
"remove"
icon-classes=
"mr-2"
@
click=
"deleteEntry(path)"
/>
</li>
</ul>
</div>
</div>
...
...
app/assets/javascripts/ide/components/repo_commit_section.vue
View file @
cded268c
...
...
@@ -44,7 +44,7 @@ export default {
},
},
mounted
()
{
if
(
this
.
lastOpenedFile
)
{
if
(
this
.
lastOpenedFile
&&
this
.
lastOpenedFile
.
type
!==
'
tree
'
)
{
this
.
openPendingTab
({
file
:
this
.
lastOpenedFile
,
keyPrefix
:
this
.
lastOpenedFile
.
changed
?
stageKeys
.
unstaged
:
stageKeys
.
staged
,
...
...
app/assets/javascripts/ide/components/repo_editor.vue
View file @
cded268c
...
...
@@ -87,7 +87,9 @@ export default {
this
.
editor
.
updateDimensions
();
},
viewer
()
{
if
(
!
this
.
file
.
pending
)
{
this
.
createEditorInstance
();
}
},
panelResizing
()
{
if
(
!
this
.
panelResizing
)
{
...
...
@@ -109,6 +111,7 @@ export default {
},
methods
:
{
...
mapActions
([
'
getFileData
'
,
'
getRawFileData
'
,
'
changeFileContent
'
,
'
setFileLanguage
'
,
...
...
@@ -123,10 +126,16 @@ export default {
this
.
editor
.
clearEditor
();
this
.
getFileData
({
path
:
this
.
file
.
path
,
makeFileActive
:
false
,
})
.
then
(()
=>
this
.
getRawFileData
({
path
:
this
.
file
.
path
,
baseSha
:
this
.
currentMergeRequest
?
this
.
currentMergeRequest
.
baseCommitSha
:
''
,
})
}),
)
.
then
(()
=>
{
this
.
createEditorInstance
();
})
...
...
@@ -246,6 +255,8 @@ export default {
ref=
"editor"
:class=
"{
'is-readonly': isCommitModeActive,
'is-deleted': file.deleted,
'is-added': file.tempFile
}"
class=
"multi-file-editor-holder"
>
...
...
app/assets/javascripts/ide/components/repo_file.vue
View file @
cded268c
...
...
@@ -34,11 +34,6 @@ export default {
type
:
Number
,
required
:
true
,
},
disableActionDropdown
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
data
()
{
return
{
...
...
@@ -212,8 +207,7 @@ export default {
/>
</span>
<new-dropdown
v-if=
"isTree && !disableActionDropdown"
:project-id=
"file.projectId"
:type=
"file.type"
:branch=
"file.branchId"
:path=
"file.path"
:mouse-over=
"mouseOver"
...
...
app/assets/javascripts/ide/components/repo_tab.vue
View file @
cded268c
...
...
@@ -37,7 +37,7 @@ export default {
return
this
.
fileHasChanged
?
!
this
.
tabMouseOver
:
false
;
},
fileHasChanged
()
{
return
this
.
tab
.
changed
||
this
.
tab
.
tempFile
||
this
.
tab
.
staged
;
return
this
.
tab
.
changed
||
this
.
tab
.
tempFile
||
this
.
tab
.
staged
||
this
.
tab
.
deleted
;
},
},
...
...
@@ -71,7 +71,8 @@ export default {
<
template
>
<li
:class=
"
{
active: tab.active
active: tab.active,
disabled: tab.pending
}"
@click="clickFile(tab)"
@mouseover="mouseOverTab"
...
...
@@ -105,7 +106,6 @@ export default {
<changed-file-icon
v-else
:file=
"tab"
:force-modified-icon=
"true"
/>
</button>
</li>
...
...
app/assets/javascripts/ide/constants.js
View file @
cded268c
...
...
@@ -38,3 +38,18 @@ export const stageKeys = {
unstaged
:
'
unstaged
'
,
staged
:
'
staged
'
,
};
export
const
commitItemIconMap
=
{
addition
:
{
icon
:
'
file-addition
'
,
class
:
'
ide-file-addition
'
,
},
modified
:
{
icon
:
'
file-modified
'
,
class
:
'
ide-file-modified
'
,
},
deleted
:
{
icon
:
'
file-deletion
'
,
class
:
'
ide-file-deletion
'
,
},
};
app/assets/javascripts/ide/lib/common/model.js
View file @
cded268c
...
...
@@ -7,7 +7,7 @@ export default class Model {
this
.
disposable
=
new
Disposable
();
this
.
file
=
file
;
this
.
head
=
head
;
this
.
content
=
file
.
content
!==
''
?
file
.
content
:
file
.
raw
;
this
.
content
=
file
.
content
!==
''
||
file
.
deleted
?
file
.
content
:
file
.
raw
;
this
.
disposable
.
add
(
(
this
.
originalModel
=
monacoEditor
.
createModel
(
...
...
app/assets/javascripts/ide/stores/actions.js
View file @
cded268c
...
...
@@ -185,6 +185,14 @@ export const openNewEntryModal = ({ commit }, { type, path = '' }) => {
$
(
'
#ide-new-entry
'
).
modal
(
'
show
'
);
};
export
const
deleteEntry
=
({
commit
,
dispatch
,
state
},
path
)
=>
{
dispatch
(
'
burstUnusedSeal
'
);
dispatch
(
'
closeFile
'
,
state
.
entries
[
path
]);
commit
(
types
.
DELETE_ENTRY
,
path
);
};
export
const
resetOpenFiles
=
({
commit
})
=>
commit
(
types
.
RESET_OPEN_FILES
);
export
*
from
'
./actions/tree
'
;
export
*
from
'
./actions/file
'
;
export
*
from
'
./actions/project
'
;
...
...
app/assets/javascripts/ide/stores/actions/file.js
View file @
cded268c
...
...
@@ -61,7 +61,11 @@ export const setFileActive = ({ commit, state, getters, dispatch }, path) => {
export
const
getFileData
=
({
state
,
commit
,
dispatch
},
{
path
,
makeFileActive
=
true
})
=>
{
const
file
=
state
.
entries
[
path
];
if
(
file
.
raw
||
file
.
tempFile
)
return
Promise
.
resolve
();
commit
(
types
.
TOGGLE_LOADING
,
{
entry
:
file
});
return
service
.
getFileData
(
`
${
gon
.
relative_url_root
?
gon
.
relative_url_root
:
''
}${
file
.
url
.
replace
(
'
/-/
'
,
'
/
'
)}
`
,
...
...
@@ -71,7 +75,7 @@ export const getFileData = ({ state, commit, dispatch }, { path, makeFileActive
setPageTitle
(
decodeURI
(
normalizedHeaders
[
'
PAGE-TITLE
'
]));
commit
(
types
.
SET_FILE_DATA
,
{
data
,
file
});
commit
(
types
.
TOGGLE_FILE_OPEN
,
path
);
if
(
makeFileActive
)
commit
(
types
.
TOGGLE_FILE_OPEN
,
path
);
if
(
makeFileActive
)
dispatch
(
'
setFileActive
'
,
path
);
commit
(
types
.
TOGGLE_LOADING
,
{
entry
:
file
});
})
...
...
@@ -97,7 +101,7 @@ export const getRawFileData = ({ state, commit, dispatch }, { path, baseSha }) =
service
.
getRawFileData
(
file
)
.
then
(
raw
=>
{
commit
(
types
.
SET_FILE_RAW_DATA
,
{
file
,
raw
});
if
(
!
file
.
tempFile
)
commit
(
types
.
SET_FILE_RAW_DATA
,
{
file
,
raw
});
if
(
file
.
mrChange
&&
file
.
mrChange
.
new_file
===
false
)
{
service
.
getBaseRawFileData
(
file
,
baseSha
)
...
...
app/assets/javascripts/ide/stores/actions/tree.js
View file @
cded268c
...
...
@@ -21,14 +21,12 @@ export const showTreeEntry = ({ commit, dispatch, state }, path) => {
export
const
handleTreeEntryAction
=
({
commit
,
dispatch
},
row
)
=>
{
if
(
row
.
type
===
'
tree
'
)
{
dispatch
(
'
toggleTreeOpen
'
,
row
.
path
);
}
else
if
(
row
.
type
===
'
blob
'
&&
(
row
.
opened
||
row
.
changed
)
)
{
if
(
row
.
changed
&&
!
row
.
opened
)
{
}
else
if
(
row
.
type
===
'
blob
'
)
{
if
(
!
row
.
opened
)
{
commit
(
types
.
TOGGLE_FILE_OPEN
,
row
.
path
);
}
dispatch
(
'
setFileActive
'
,
row
.
path
);
}
else
{
dispatch
(
'
getFileData
'
,
{
path
:
row
.
path
});
}
dispatch
(
'
showTreeEntry
'
,
row
.
path
);
...
...
app/assets/javascripts/ide/stores/modules/commit/actions.js
View file @
cded268c
...
...
@@ -174,12 +174,14 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo
dispatch
(
'
updateActivityBarView
'
,
activityBarViews
.
edit
,
{
root
:
true
});
dispatch
(
'
updateViewer
'
,
'
editor
'
,
{
root
:
true
});
if
(
rootGetters
.
activeFile
)
{
router
.
push
(
`/project/
${
rootState
.
currentProjectId
}
/blob/
${
getters
.
branchName
}
/-/
${
rootGetters
.
activeFile
.
path
}
`
,
);
}
}
})
.
then
(()
=>
dispatch
(
'
updateCommitAction
'
,
consts
.
COMMIT_TO_CURRENT_BRANCH
))
.
then
(()
=>
...
...
app/assets/javascripts/ide/stores/modules/commit/getters.js
View file @
cded268c
import
{
sprintf
,
n__
}
from
'
../../../../locale
'
;
import
{
sprintf
,
n__
,
__
}
from
'
../../../../locale
'
;
import
*
as
consts
from
'
./constants
'
;
const
BRANCH_SUFFIX_COUNT
=
5
;
const
createTranslatedTextForFiles
=
(
files
,
text
)
=>
{
if
(
!
files
.
length
)
return
null
;
return
sprintf
(
n__
(
'
%{text} %{files}
'
,
'
%{text} %{files} files
'
,
files
.
length
),
{
files
:
files
.
reduce
((
acc
,
val
)
=>
acc
.
concat
(
val
.
path
),
[]).
join
(
'
,
'
),
text
,
});
};
export
const
discardDraftButtonDisabled
=
state
=>
state
.
commitMessage
===
''
||
state
.
submitCommitLoading
;
...
...
@@ -29,14 +37,16 @@ export const branchName = (state, getters, rootState) => {
export
const
preBuiltCommitMessage
=
(
state
,
_
,
rootState
)
=>
{
if
(
state
.
commitMessage
)
return
state
.
commitMessage
;
const
files
=
(
rootState
.
stagedFiles
.
length
?
rootState
.
stagedFiles
:
rootState
.
changedFiles
).
reduce
((
acc
,
val
)
=>
acc
.
concat
(
val
.
path
),
[]);
const
files
=
rootState
.
stagedFiles
.
length
?
rootState
.
stagedFiles
:
rootState
.
changedFiles
;
const
modifiedFiles
=
files
.
filter
(
f
=>
!
f
.
deleted
);
const
deletedFiles
=
files
.
filter
(
f
=>
f
.
deleted
);
return
sprintf
(
n__
(
'
Update %{files}
'
,
'
Update %{files} files
'
,
files
.
length
),
{
files
:
files
.
join
(
'
,
'
),
});
return
[
createTranslatedTextForFiles
(
modifiedFiles
,
__
(
'
Update
'
)),
createTranslatedTextForFiles
(
deletedFiles
,
__
(
'
Deleted
'
)),
]
.
filter
(
t
=>
t
)
.
join
(
'
\n
'
);
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests
...
...
app/assets/javascripts/ide/stores/mutation_types.js
View file @
cded268c
...
...
@@ -76,3 +76,4 @@ export const RESET_OPEN_FILES = 'RESET_OPEN_FILES';
export
const
SET_ERROR_MESSAGE
=
'
SET_ERROR_MESSAGE
'
;
export
const
OPEN_NEW_ENTRY_MODAL
=
'
OPEN_NEW_ENTRY_MODAL
'
;
export
const
DELETE_ENTRY
=
'
DELETE_ENTRY
'
;
app/assets/javascripts/ide/stores/mutations.js
View file @
cded268c
/* eslint-disable no-param-reassign */
import
*
as
types
from
'
./mutation_types
'
;
import
projectMutations
from
'
./mutations/project
'
;
import
mergeRequestMutation
from
'
./mutations/merge_request
'
;
...
...
@@ -171,6 +172,16 @@ export default {
newEntryModal
:
{
type
,
path
},
});
},
[
types
.
DELETE_ENTRY
](
state
,
path
)
{
const
entry
=
state
.
entries
[
path
];
const
parent
=
entry
.
parentPath
?
state
.
entries
[
entry
.
parentPath
]
:
state
.
trees
[
`
${
state
.
currentProjectId
}
/
${
state
.
currentBranchId
}
`
];
entry
.
deleted
=
true
;
state
.
changedFiles
=
state
.
changedFiles
.
concat
(
entry
);
parent
.
tree
=
parent
.
tree
.
filter
(
f
=>
f
.
path
!==
entry
.
path
);
},
...
projectMutations
,
...
mergeRequestMutation
,
...
fileMutations
,
...
...
app/assets/javascripts/ide/stores/mutations/file.js
View file @
cded268c
/* eslint-disable no-param-reassign */
import
*
as
types
from
'
../mutation_types
'
;
import
{
sortTree
}
from
'
../utils
'
;
import
{
diffModes
}
from
'
../../constants
'
;
export
default
{
...
...
@@ -51,9 +52,17 @@ export default {
});
},
[
types
.
SET_FILE_RAW_DATA
](
state
,
{
file
,
raw
})
{
const
openPendingFile
=
state
.
openFiles
.
find
(
f
=>
f
.
path
===
file
.
path
&&
f
.
pending
&&
!
f
.
tempFile
,
);
Object
.
assign
(
state
.
entries
[
file
.
path
],
{
raw
,
});
if
(
openPendingFile
)
{
openPendingFile
.
raw
=
raw
;
}
},
[
types
.
SET_FILE_BASE_RAW_DATA
](
state
,
{
file
,
baseRaw
})
{
Object
.
assign
(
state
.
entries
[
file
.
path
],
{
...
...
@@ -109,11 +118,22 @@ export default {
},
[
types
.
DISCARD_FILE_CHANGES
](
state
,
path
)
{
const
stagedFile
=
state
.
stagedFiles
.
find
(
f
=>
f
.
path
===
path
);
const
entry
=
state
.
entries
[
path
];
const
{
deleted
}
=
entry
;
Object
.
assign
(
state
.
entries
[
path
],
{
content
:
stagedFile
?
stagedFile
.
content
:
state
.
entries
[
path
].
raw
,
changed
:
false
,
deleted
:
false
,
});
if
(
deleted
)
{
const
parent
=
entry
.
parentPath
?
state
.
entries
[
entry
.
parentPath
]
:
state
.
trees
[
`
${
state
.
currentProjectId
}
/
${
state
.
currentBranchId
}
`
];
parent
.
tree
=
sortTree
(
parent
.
tree
.
concat
(
entry
));
}
},
[
types
.
ADD_FILE_TO_CHANGED
](
state
,
path
)
{
Object
.
assign
(
state
,
{
...
...
app/assets/javascripts/ide/stores/utils.js
View file @
cded268c
...
...
@@ -46,6 +46,7 @@ export const dataStructure = () => ({
parentPath
:
null
,
lastOpenedAt
:
0
,
mrChange
:
null
,
deleted
:
false
,
});
export
const
decorateData
=
entity
=>
{
...
...
@@ -105,15 +106,37 @@ export const setPageTitle = title => {
document
.
title
=
title
;
};
export
const
commitActionForFile
=
file
=>
{
if
(
file
.
deleted
)
{
return
'
delete
'
;
}
else
if
(
file
.
tempFile
)
{
return
'
create
'
;
}
return
'
update
'
;
};
export
const
getCommitFiles
=
(
stagedFiles
,
deleteTree
=
false
)
=>
stagedFiles
.
reduce
((
acc
,
file
)
=>
{
if
((
file
.
deleted
||
deleteTree
)
&&
file
.
type
===
'
tree
'
)
{
return
acc
.
concat
(
getCommitFiles
(
file
.
tree
,
true
));
}
return
acc
.
concat
({
...
file
,
deleted
:
deleteTree
||
file
.
deleted
,
});
},
[]);
export
const
createCommitPayload
=
({
branch
,
getters
,
newBranch
,
state
,
rootState
})
=>
({
branch
,
commit_message
:
state
.
commitMessage
||
getters
.
preBuiltCommitMessage
,
actions
:
rootState
.
stagedFiles
.
map
(
f
=>
({
action
:
f
.
tempFile
?
'
create
'
:
'
update
'
,
actions
:
getCommitFiles
(
rootState
.
stagedFiles
)
.
map
(
f
=>
({
action
:
commitActionForFile
(
f
)
,
file_path
:
f
.
path
,
content
:
f
.
content
,
encoding
:
f
.
base64
?
'
base64
'
:
'
text
'
,
last_commit_id
:
newBranch
?
undefined
:
f
.
lastCommitSha
,
last_commit_id
:
newBranch
||
f
.
deleted
?
undefined
:
f
.
lastCommitSha
,
})),
start_branch
:
newBranch
?
rootState
.
currentBranchId
:
undefined
,
});
...
...
app/assets/javascripts/ide/utils.js
0 → 100644
View file @
cded268c
import
{
commitItemIconMap
}
from
'
./constants
'
;
// eslint-disable-next-line import/prefer-default-export
export
const
getCommitIconMap
=
file
=>
{
if
(
file
.
deleted
)
{
return
commitItemIconMap
.
deleted
;
}
else
if
(
file
.
tempFile
)
{
return
commitItemIconMap
.
addition
;
}
return
commitItemIconMap
.
modified
;
};
app/assets/stylesheets/page_bundles/ide.scss
View file @
cded268c
...
...
@@ -77,6 +77,7 @@
.ide-file-icon-holder
{
display
:
flex
;
align-items
:
center
;
color
:
$theme-gray-700
;
}
.ide-file-changed-icon
{
...
...
@@ -164,12 +165,23 @@
background-color
:
$white-light
;
border-bottom-color
:
$white-light
;
}
&
:not
(
.disabled
)
{
.multi-file-tab
{
cursor
:
pointer
;
}
}
&
.disabled
{
.multi-file-tab-close
{
cursor
:
default
;
}
}
}
}
.multi-file-tab
{
@include
str-truncated
(
141px
);
cursor
:
pointer
;
svg
{
vertical-align
:
middle
;
...
...
@@ -244,6 +256,38 @@
}
}
.is-deleted
{
.editor.modified
{
.margin-view-overlays
,
.lines-content
,
.decorationsOverviewRuler
{
// !important to override monaco inline styles
display
:
none
!
important
;
}
}
.diffOverviewRuler.modified
{
// !important to override monaco inline styles
display
:
none
!
important
;
}
}
.is-added
{
.editor.original
{
.margin-view-overlays
,
.lines-content
,
.decorationsOverviewRuler
{
// !important to override monaco inline styles
display
:
none
!
important
;
}
}
.diffOverviewRuler.original
{
// !important to override monaco inline styles
display
:
none
!
important
;
}
}
.monaco-diff-editor.vs
{
.editor.modified
{
box-shadow
:
none
;
...
...
@@ -560,16 +604,21 @@
}
}
.
multi
-file-addition
,
.
multi
-file-addition-solid
{
.
ide
-file-addition
,
.
ide
-file-addition-solid
{
color
:
$green-500
;
}
.
multi
-file-modified
,
.
multi
-file-modified-solid
{
.
ide
-file-modified
,
.
ide
-file-modified-solid
{
color
:
$orange-500
;
}
.ide-file-deletion
,
.ide-file-deletion-solid
{
color
:
$red-500
;
}
.multi-file-commit-list-collapsed
{
display
:
flex
;
flex-direction
:
column
;
...
...
@@ -1017,6 +1066,10 @@
.ide-new-btn
{
margin-left
:
auto
;
}
button
{
color
:
$gl-text-color
;
}
}
.ide-sidebar-branch-title
{
...
...
changelogs/unreleased/ide-delete-entries.yml
0 → 100644
View file @
cded268c
---
title
:
Enabled deletion of files in the Web IDE
merge_request
:
author
:
type
:
added
locale/gitlab.pot
View file @
cded268c
...
...
@@ -122,6 +122,11 @@ msgid_plural "%{storage_name}: %{failed_attempts} failed storage access attempts
msgstr[0] ""
msgstr[1] ""
msgid "%{text} %{files}"
msgid_plural "%{text} %{files} files"
msgstr[0] ""
msgstr[1] ""
msgid "%{text} is available"
msgstr ""
...
...
@@ -1992,6 +1997,9 @@ msgstr ""
msgid "Delete list"
msgstr ""
msgid "Deleted"
msgstr ""
msgid "Deny"
msgstr ""
...
...
@@ -5537,10 +5545,8 @@ msgstr ""
msgid "Up to date"
msgstr ""
msgid "Update %{files}"
msgid_plural "Update %{files} files"
msgstr[0] ""
msgstr[1] ""
msgid "Update"
msgstr ""
msgid "Update your group name, description, avatar, and other general settings."
msgstr ""
...
...
spec/javascripts/ide/components/changed_file_icon_spec.js
View file @
cded268c
...
...
@@ -33,14 +33,14 @@ describe('IDE changed file icon', () => {
});
describe
(
'
changedIconClass
'
,
()
=>
{
it
(
'
includes
multi
-file-modified when not a temp file
'
,
()
=>
{
expect
(
vm
.
changedIconClass
).
toContain
(
'
multi
-file-modified
'
);
it
(
'
includes
ide
-file-modified when not a temp file
'
,
()
=>
{
expect
(
vm
.
changedIconClass
).
toContain
(
'
ide
-file-modified
'
);
});
it
(
'
includes
multi
-file-addition when a temp file
'
,
()
=>
{
it
(
'
includes
ide
-file-addition when a temp file
'
,
()
=>
{
vm
.
file
.
tempFile
=
true
;
expect
(
vm
.
changedIconClass
).
toContain
(
'
multi
-file-addition
'
);
expect
(
vm
.
changedIconClass
).
toContain
(
'
ide
-file-addition
'
);
});
});
});
spec/javascripts/ide/components/commit_sidebar/list_item_spec.js
View file @
cded268c
...
...
@@ -76,17 +76,29 @@ describe('Multi-file editor commit sidebar list item', () => {
expect
(
vm
.
iconName
).
toBe
(
'
file-addition
'
);
});
it
(
'
returns deletion
'
,
()
=>
{
f
.
deleted
=
true
;
expect
(
vm
.
iconName
).
toBe
(
'
file-deletion
'
);
});
});
describe
(
'
iconClass
'
,
()
=>
{
it
(
'
returns modified when not a tempFile
'
,
()
=>
{
expect
(
vm
.
iconClass
).
toContain
(
'
multi
-file-modified
'
);
expect
(
vm
.
iconClass
).
toContain
(
'
ide
-file-modified
'
);
});
it
(
'
returns addition when not a tempFile
'
,
()
=>
{
f
.
tempFile
=
true
;
expect
(
vm
.
iconClass
).
toContain
(
'
multi-file-addition
'
);
expect
(
vm
.
iconClass
).
toContain
(
'
ide-file-addition
'
);
});
it
(
'
returns deletion
'
,
()
=>
{
f
.
deleted
=
true
;
expect
(
vm
.
iconClass
).
toContain
(
'
ide-file-deletion
'
);
});
});
});
...
...
spec/javascripts/ide/components/new_dropdown/index_spec.js
View file @
cded268c
...
...
@@ -14,6 +14,7 @@ describe('new dropdown component', () => {
branch
:
'
master
'
,
path
:
''
,
mouseOver
:
false
,
type
:
'
tree
'
,
});
vm
.
$store
.
state
.
currentProjectId
=
'
abcproject
'
;
...
...
@@ -67,4 +68,14 @@ describe('new dropdown component', () => {
});
});
});
describe
(
'
delete entry
'
,
()
=>
{
it
(
'
calls delete action
'
,
()
=>
{
spyOn
(
vm
,
'
deleteEntry
'
);
vm
.
$el
.
querySelectorAll
(
'
.dropdown-menu button
'
)[
3
].
click
();
expect
(
vm
.
deleteEntry
).
toHaveBeenCalledWith
(
''
);
});
});
});
spec/javascripts/ide/components/repo_editor_spec.js
View file @
cded268c
import
Vue
from
'
vue
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
'
~/behaviors/markdown/render_gfm
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
store
from
'
~/ide/stores
'
;
import
repoEditor
from
'
~/ide/components/repo_editor.vue
'
;
...
...
@@ -25,6 +26,8 @@ describe('RepoEditor', () => {
vm
.
$store
.
state
.
openFiles
.
push
(
f
);
Vue
.
set
(
vm
.
$store
.
state
.
entries
,
f
.
path
,
f
);
spyOn
(
vm
,
'
getFileData
'
).
and
.
returnValue
(
Promise
.
resolve
());
vm
.
$mount
();
Vue
.
nextTick
(()
=>
setTimeout
(
done
));
...
...
spec/javascripts/ide/components/repo_file_spec.js
View file @
cded268c
...
...
@@ -91,25 +91,6 @@ describe('RepoFile', () => {
done
();
});
});
it
(
'
disables action dropdown
'
,
done
=>
{
createComponent
({
file
:
{
...
file
(
'
t4
'
),
type
:
'
tree
'
,
branchId
:
'
master
'
,
projectId
:
'
project
'
,
},
level
:
0
,
disableActionDropdown
:
true
,
});
setTimeout
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.ide-new-btn
'
)).
toBeNull
();
done
();
});
});
});
describe
(
'
locked file
'
,
()
=>
{
...
...
spec/javascripts/ide/components/repo_tab_spec.js
View file @
cded268c
...
...
@@ -93,13 +93,13 @@ describe('RepoTab', () => {
Vue
.
nextTick
()
.
then
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.
multi
-file-modified
'
)).
toBeNull
();
expect
(
vm
.
$el
.
querySelector
(
'
.
ide
-file-modified
'
)).
toBeNull
();
vm
.
$el
.
dispatchEvent
(
new
Event
(
'
mouseout
'
));
})
.
then
(
Vue
.
nextTick
)
.
then
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.
multi
-file-modified
'
)).
not
.
toBeNull
();
expect
(
vm
.
$el
.
querySelector
(
'
.
ide
-file-modified
'
)).
not
.
toBeNull
();
done
();
})
...
...
spec/javascripts/ide/stores/actions_spec.js
View file @
cded268c
...
...
@@ -7,6 +7,7 @@ import actions, {
updateActivityBarView
,
updateTempFlagForEntry
,
setErrorMessage
,
deleteEntry
,
}
from
'
~/ide/stores/actions
'
;
import
store
from
'
~/ide/stores
'
;
import
*
as
types
from
'
~/ide/stores/mutation_types
'
;
...
...
@@ -457,4 +458,19 @@ describe('Multi-file store actions', () => {
);
});
});
describe
(
'
deleteEntry
'
,
()
=>
{
it
(
'
commits entry deletion
'
,
done
=>
{
store
.
state
.
entries
.
path
=
'
testing
'
;
testAction
(
deleteEntry
,
'
path
'
,
store
.
state
,
[{
type
:
types
.
DELETE_ENTRY
,
payload
:
'
path
'
}],
[{
type
:
'
burstUnusedSeal
'
},
{
type
:
'
closeFile
'
,
payload
:
store
.
state
.
entries
.
path
}],
done
,
);
});
});
});
spec/javascripts/ide/stores/modules/commit/getters_spec.js
View file @
cded268c
...
...
@@ -123,6 +123,22 @@ describe('IDE commit module getters', () => {
'
Update test-file, index.js files
'
,
);
});
it
(
'
returns commitMessage with deleted files
'
,
()
=>
{
rootState
[
key
].
push
(
{
path
:
'
test-file
'
,
deleted
:
true
,
},
{
path
:
'
index.js
'
,
},
);
expect
(
getters
.
preBuiltCommitMessage
(
state
,
null
,
rootState
)).
toBe
(
'
Update index.js
\n
Deleted test-file
'
,
);
});
});
});
});
spec/javascripts/ide/stores/mutations/file_spec.js
View file @
cded268c
...
...
@@ -94,6 +94,35 @@ describe('IDE store file mutations', () => {
expect
(
localFile
.
raw
).
toBe
(
'
testing
'
);
});
it
(
'
adds raw data to open pending file
'
,
()
=>
{
localState
.
openFiles
.
push
({
...
localFile
,
pending
:
true
,
});
mutations
.
SET_FILE_RAW_DATA
(
localState
,
{
file
:
localFile
,
raw
:
'
testing
'
,
});
expect
(
localState
.
openFiles
[
0
].
raw
).
toBe
(
'
testing
'
);
});
it
(
'
does not add raw data to open pending tempFile file
'
,
()
=>
{
localState
.
openFiles
.
push
({
...
localFile
,
pending
:
true
,
tempFile
:
true
,
});
mutations
.
SET_FILE_RAW_DATA
(
localState
,
{
file
:
localFile
,
raw
:
'
testing
'
,
});
expect
(
localState
.
openFiles
[
0
].
raw
).
not
.
toBe
(
'
testing
'
);
});
});
describe
(
'
SET_FILE_BASE_RAW_DATA
'
,
()
=>
{
...
...
@@ -205,6 +234,11 @@ describe('IDE store file mutations', () => {
beforeEach
(()
=>
{
localFile
.
content
=
'
test
'
;
localFile
.
changed
=
true
;
localState
.
currentProjectId
=
'
gitlab-ce
'
;
localState
.
currentBranchId
=
'
master
'
;
localState
.
trees
[
'
gitlab-ce/master
'
]
=
{
tree
:
[],
};
});
it
(
'
resets content and changed
'
,
()
=>
{
...
...
@@ -213,6 +247,36 @@ describe('IDE store file mutations', () => {
expect
(
localFile
.
content
).
toBe
(
''
);
expect
(
localFile
.
changed
).
toBeFalsy
();
});
it
(
'
adds to root tree if deleted
'
,
()
=>
{
localFile
.
deleted
=
true
;
mutations
.
DISCARD_FILE_CHANGES
(
localState
,
localFile
.
path
);
expect
(
localState
.
trees
[
'
gitlab-ce/master
'
].
tree
).
toEqual
([
{
...
localFile
,
deleted
:
false
,
},
]);
});
it
(
'
adds to parent tree if deleted
'
,
()
=>
{
localFile
.
deleted
=
true
;
localFile
.
parentPath
=
'
parentPath
'
;
localState
.
entries
.
parentPath
=
{
tree
:
[],
};
mutations
.
DISCARD_FILE_CHANGES
(
localState
,
localFile
.
path
);
expect
(
localState
.
entries
.
parentPath
.
tree
).
toEqual
([
{
...
localFile
,
deleted
:
false
,
},
]);
});
});
describe
(
'
ADD_FILE_TO_CHANGED
'
,
()
=>
{
...
...
spec/javascripts/ide/stores/mutations_spec.js
View file @
cded268c
...
...
@@ -156,4 +156,61 @@ describe('Multi-file store mutations', () => {
expect
(
localState
.
errorMessage
).
toBe
(
'
error
'
);
});
});
describe
(
'
DELETE_ENTRY
'
,
()
=>
{
beforeEach
(()
=>
{
localState
.
currentProjectId
=
'
gitlab-ce
'
;
localState
.
currentBranchId
=
'
master
'
;
localState
.
trees
[
'
gitlab-ce/master
'
]
=
{
tree
:
[],
};
});
it
(
'
sets deleted flag
'
,
()
=>
{
localState
.
entries
.
filePath
=
{
deleted
:
false
,
};
mutations
.
DELETE_ENTRY
(
localState
,
'
filePath
'
);
expect
(
localState
.
entries
.
filePath
.
deleted
).
toBe
(
true
);
});
it
(
'
removes from root tree
'
,
()
=>
{
localState
.
entries
.
filePath
=
{
path
:
'
filePath
'
,
deleted
:
false
,
};
localState
.
trees
[
'
gitlab-ce/master
'
].
tree
.
push
(
localState
.
entries
.
filePath
);
mutations
.
DELETE_ENTRY
(
localState
,
'
filePath
'
);
expect
(
localState
.
trees
[
'
gitlab-ce/master
'
].
tree
).
toEqual
([]);
});
it
(
'
removes from parent tree
'
,
()
=>
{
localState
.
entries
.
filePath
=
{
path
:
'
filePath
'
,
deleted
:
false
,
parentPath
:
'
parentPath
'
,
};
localState
.
entries
.
parentPath
=
{
tree
:
[
localState
.
entries
.
filePath
],
};
mutations
.
DELETE_ENTRY
(
localState
,
'
filePath
'
);
expect
(
localState
.
entries
.
parentPath
.
tree
).
toEqual
([]);
});
it
(
'
adds to changedFiles
'
,
()
=>
{
localState
.
entries
.
filePath
=
{
deleted
:
false
,
};
mutations
.
DELETE_ENTRY
(
localState
,
'
filePath
'
);
expect
(
localState
.
changedFiles
).
toEqual
([
localState
.
entries
.
filePath
]);
});
});
});
spec/javascripts/ide/stores/utils_spec.js
View file @
cded268c
...
...
@@ -86,6 +86,11 @@ describe('Multi-file store utils', () => {
base64
:
true
,
lastCommitSha
:
'
123456789
'
,
},
{
...
file
(
'
deletedFile
'
),
path
:
'
deletedFile
'
,
deleted
:
true
,
},
],
currentBranchId
:
'
master
'
,
};
...
...
@@ -115,6 +120,13 @@ describe('Multi-file store utils', () => {
encoding
:
'
base64
'
,
last_commit_id
:
'
123456789
'
,
},
{
action
:
'
delete
'
,
file_path
:
'
deletedFile
'
,
content
:
''
,
encoding
:
'
text
'
,
last_commit_id
:
undefined
,
},
],
start_branch
:
undefined
,
});
...
...
@@ -173,4 +185,65 @@ describe('Multi-file store utils', () => {
});
});
});
describe
(
'
commitActionForFile
'
,
()
=>
{
it
(
'
returns deleted for deleted file
'
,
()
=>
{
expect
(
utils
.
commitActionForFile
({
deleted
:
true
})).
toBe
(
'
delete
'
);
});
it
(
'
returns create for tempFile
'
,
()
=>
{
expect
(
utils
.
commitActionForFile
({
tempFile
:
true
})).
toBe
(
'
create
'
);
});
it
(
'
returns update by default
'
,
()
=>
{
expect
(
utils
.
commitActionForFile
({})).
toBe
(
'
update
'
);
});
});
describe
(
'
getCommitFiles
'
,
()
=>
{
it
(
'
returns flattened list of files and folders
'
,
()
=>
{
const
files
=
[
{
path
:
'
a
'
,
type
:
'
blob
'
,
deleted
:
true
,
},
{
path
:
'
b
'
,
type
:
'
tree
'
,
deleted
:
true
,
tree
:
[
{
path
:
'
c
'
,
type
:
'
blob
'
,
},
{
path
:
'
d
'
,
type
:
'
blob
'
,
},
],
},
];
const
flattendFiles
=
utils
.
getCommitFiles
(
files
);
expect
(
flattendFiles
).
toEqual
([
{
path
:
'
a
'
,
type
:
'
blob
'
,
deleted
:
true
,
},
{
path
:
'
c
'
,
type
:
'
blob
'
,
deleted
:
true
,
},
{
path
:
'
d
'
,
type
:
'
blob
'
,
deleted
:
true
,
},
]);
});
});
});
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