Открыть боковую панель
GitLab.org
Gitlab
Коммиты
3551d6a3
Коммит
3551d6a3
создал
Мар 20, 2018
по автору
Filipa Lacerda
Просмотр файлов
Merge branch 'ide-code-cleanup' into 'master'
Tidy up IDE code See merge request gitlab-org/gitlab-ee!4951
владельцы
a258b730
79137a95
Изменения
61
Скрыть пробелы
Построчно
Рядом
app/assets/stylesheets/pages/repo.scss
Просмотр файла @
3551d6a3
...
...
@@ -68,7 +68,6 @@
.ide-new-btn
{
display
:
none
;
margin-top
:
-4px
;
margin-bottom
:
-4px
;
margin-right
:
-8px
;
}
...
...
@@ -84,7 +83,6 @@
fill
:
$gl-text-color-secondary
;
}
}
}
a
{
...
...
@@ -290,7 +288,7 @@
.margin-view-overlays
.insert-sign
,
.margin-view-overlays
.delete-sign
{
opacity
:
.4
;
opacity
:
0
.4
;
}
}
}
...
...
@@ -548,7 +546,6 @@
height
:
10px
;
margin-left
:
3px
;
}
}
.multi-file-commit-list-path
{
...
...
@@ -626,7 +623,7 @@
top
:
0
;
width
:
100px
;
height
:
1px
;
background-color
:
rgba
(
$red-500
,
.5
);
background-color
:
rgba
(
$red-500
,
0
.5
);
}
}
}
...
...
@@ -720,12 +717,13 @@
}
.ide-view
{
height
:
calc
(
100vh
-
#{
$header-height
+
$performance-bar-height
+
$flash-height
}
);
height
:
calc
(
100vh
-
#{
$header-height
+
$performance-bar-height
+
$flash-height
}
);
}
}
}
.dragHandle
{
position
:
absolute
;
top
:
0
;
...
...
ee/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
Просмотр файла @
3551d6a3
...
...
@@ -52,7 +52,7 @@
<button
type=
"button"
class=
"btn btn-blank multi-file-discard-btn"
@
click=
"discardFileChanges(file)"
@
click=
"discardFileChanges(file
.path
)"
>
Discard
</button>
...
...
ee/app/assets/javascripts/ide/components/ide.vue
Просмотр файла @
3551d6a3
...
...
@@ -5,7 +5,6 @@
import
repoTabs
from
'
./repo_tabs.vue
'
;
import
repoFileButtons
from
'
./repo_file_buttons.vue
'
;
import
ideStatusBar
from
'
./ide_status_bar.vue
'
;
import
repoPreview
from
'
./repo_preview.vue
'
;
import
repoEditor
from
'
./repo_editor.vue
'
;
export
default
{
...
...
@@ -16,7 +15,6 @@
repoFileButtons
,
ideStatusBar
,
repoEditor
,
repoPreview
,
},
props
:
{
emptyStateSvgPath
:
{
...
...
@@ -33,18 +31,12 @@
},
},
computed
:
{
...
mapState
([
'
currentBlobView
'
,
'
selectedFile
'
,
'
changedFiles
'
,
]),
...
mapGetters
([
'
activeFile
'
,
]),
...
mapState
([
'
changedFiles
'
,
'
openFiles
'
,
'
viewer
'
]),
...
mapGetters
([
'
activeFile
'
,
'
hasChanges
'
]),
},
mounted
()
{
const
returnValue
=
'
Are you sure you want to lose unsaved changes?
'
;
window
.
onbeforeunload
=
(
e
)
=>
{
window
.
onbeforeunload
=
e
=>
{
if
(
!
this
.
changedFiles
.
length
)
return
undefined
;
Object
.
assign
(
e
,
{
...
...
@@ -67,20 +59,29 @@
<template
v-if=
"activeFile"
>
<repo-tabs/>
<component
<repo-tabs
:files=
"openFiles"
:viewer=
"viewer"
:has-changes=
"hasChanges"
/>
<repo-editor
class=
"multi-file-edit-pane-content"
:is=
"currentBlobView"
:file=
"activeFile"
/>
<repo-file-buttons
:file=
"activeFile"
/>
<repo-file-buttons
/>
<ide-status-bar
:file=
"
selected
File"
:file=
"
active
File"
/>
</
template
>
<
template
v-else
>
<div
class=
"ide-empty-state"
>
<div
v-once
class=
"ide-empty-state"
>
<div
class=
"row js-empty-state"
>
<div
class=
"col-xs-12"
>
<div
class=
"svg-content svg-250"
>
...
...
ee/app/assets/javascripts/ide/components/ide_context_bar.vue
Просмотр файла @
3551d6a3
<
script
>
import
{
mapState
,
mapActions
}
from
'
vuex
'
;
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
panelResizer
from
'
~/vue_shared/components/panel_resizer.vue
'
;
import
repoCommitSection
from
'
./repo_commit_section.vue
'
;
import
{
mapActions
,
mapGetters
,
mapState
}
from
'
vuex
'
;
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
panelResizer
from
'
~/vue_shared/components/panel_resizer.vue
'
;
import
repoCommitSection
from
'
./repo_commit_section.vue
'
;
import
ResizablePanel
from
'
./resizable_panel.vue
'
;
export
default
{
components
:
{
repoCommitSection
,
icon
,
panelResizer
,
export
default
{
components
:
{
repoCommitSection
,
icon
,
panelResizer
,
ResizablePanel
,
},
props
:
{
noChangesStateSvgPath
:
{
type
:
String
,
required
:
true
,
},
props
:
{
noChangesStateSvgPath
:
{
type
:
String
,
required
:
true
,
},
committedStateSvgPath
:
{
type
:
String
,
required
:
true
,
},
committedStateSvgPath
:
{
type
:
String
,
required
:
true
,
},
data
()
{
return
{
width
:
340
,
};
},
computed
:
{
...
mapState
([
'
rightPanelCollapsed
'
,
'
changedFiles
'
,
]),
currentIcon
()
{
return
this
.
rightPanelCollapsed
?
'
angle-double-left
'
:
'
angle-double-right
'
;
},
maxSize
()
{
return
window
.
innerWidth
/
2
;
},
panelStyle
()
{
if
(
!
this
.
rightPanelCollapsed
)
{
return
{
width
:
`
${
this
.
width
}
px`
};
}
return
{};
},
},
methods
:
{
...
mapActions
([
'
setPanelCollapsedStatus
'
,
'
setResizingStatus
'
,
]),
toggleCollapsed
()
{
this
.
setPanelCollapsedStatus
({
side
:
'
right
'
,
collapsed
:
!
this
.
rightPanelCollapsed
,
});
},
toggleFullbarCollapsed
()
{
if
(
this
.
rightPanelCollapsed
)
{
this
.
toggleCollapsed
();
}
},
resizingStarted
()
{
this
.
setResizingStatus
(
true
);
},
resizingEnded
()
{
this
.
setResizingStatus
(
false
);
},
},
};
},
computed
:
{
...
mapState
([
'
changedFiles
'
,
'
rightPanelCollapsed
'
]),
...
mapGetters
([
'
currentIcon
'
]),
},
methods
:
{
...
mapActions
([
'
setPanelCollapsedStatus
'
]),
},
};
</
script
>
<
template
>
<div
class=
"multi-file-commit-panel"
:class=
"
{
'is-collapsed': rightPanelCollapsed,
}"
:style="panelStyle"
@click="toggleFullbarCollapsed"
<resizable-panel
:collapsible=
"true"
:initial-width=
"340"
side=
"right"
>
<div
class=
"multi-file-commit-panel-section"
...
...
@@ -104,7 +64,10 @@
<button
type=
"button"
class=
"btn btn-transparent multi-file-commit-panel-collapse-btn"
@
click.stop=
"toggleCollapsed"
@
click.stop=
"setPanelCollapsedStatus(
{
side: 'right',
collapsed: !rightPanelCollapsed,
})"
>
<icon
:name=
"currentIcon"
...
...
@@ -117,15 +80,5 @@
:committed-state-svg-path=
"committedStateSvgPath"
/>
</div>
<panel-resizer
:size.sync=
"width"
:enabled=
"!rightPanelCollapsed"
:start-size=
"340"
:min-size=
"200"
:max-size=
"maxSize"
@
resize-start=
"resizingStarted"
@
resize-end=
"resizingEnded"
side=
"left"
/>
</div>
</resizable-panel>
</
template
>
ee/app/assets/javascripts/ide/components/ide_project_branches_tree.vue
Просмотр файла @
3551d6a3
<
script
>
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
repoTree
from
'
./ide_repo_tree.vue
'
;
import
newDropdown
from
'
./new_dropdown/index.vue
'
;
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
repoTree
from
'
./ide_repo_tree.vue
'
;
import
newDropdown
from
'
./new_dropdown/index.vue
'
;
export
default
{
components
:
{
repoTree
,
icon
,
newDropdown
,
},
props
:
{
projectId
:
{
type
:
String
,
required
:
true
,
export
default
{
components
:
{
repoTree
,
icon
,
newDropdown
,
},
branch
:
{
type
:
Object
,
required
:
true
,
props
:
{
projectId
:
{
type
:
String
,
required
:
true
,
},
branch
:
{
type
:
Object
,
required
:
true
,
},
},
},
};
};
</
script
>
<
template
>
...
...
@@ -40,8 +40,8 @@ export default {
/>
</div>
</div>
<
div>
<repo-tree
:tree
-id
=
"branch.tree
Id"
/>
</div
>
<
repo-tree
:tree=
"branch.tree
"
/
>
</div>
</
template
>
ee/app/assets/javascripts/ide/components/ide_repo_tree.vue
Просмотр файла @
3551d6a3
<
script
>
import
{
mapState
}
from
'
vuex
'
;
import
skeletonLoadingContainer
from
'
~/vue_shared/components/skeleton_loading_container.vue
'
;
import
repoFile
from
'
./repo_file.vue
'
;
import
SkeletonLoadingContainer
from
'
~/vue_shared/components/skeleton_loading_container.vue
'
;
import
RepoFile
from
'
./repo_file.vue
'
;
export
default
{
components
:
{
r
epoFile
,
s
keletonLoadingContainer
,
R
epoFile
,
S
keletonLoadingContainer
,
},
props
:
{
tree
Id
:
{
type
:
String
,
tree
:
{
type
:
Object
,
required
:
true
,
},
},
computed
:
{
...
mapState
([
'
trees
'
,
]),
...
mapState
({
projectName
(
state
)
{
return
state
.
project
.
name
;
},
}),
selctedTree
()
{
return
this
.
trees
[
this
.
treeId
].
tree
;
},
showLoading
()
{
return
!
this
.
trees
[
this
.
treeId
]
||
this
.
trees
[
this
.
treeId
].
loading
;
},
},
};
</
script
>
<
template
>
<div
class=
"ide-file-list"
v-if=
"treeId"
>
<template
v-if=
"
showL
oading"
>
<template
v-if=
"
tree.l
oading"
>
<div
class=
"multi-file-loading-container"
v-for=
"n in 3"
...
...
@@ -47,10 +29,13 @@ export default {
<skeleton-loading-container
/>
</div>
</
template
>
<repo-file
v-for=
"file in selctedTree"
:key=
"file.key"
:file=
"file"
/>
<
template
v-else
>
<repo-file
v-for=
"file in tree.tree"
:key=
"file.key"
:file=
"file"
:level=
"0"
/>
</
template
>
</div>
</template>
ee/app/assets/javascripts/ide/components/ide_side_bar.vue
Просмотр файла @
3551d6a3
<
script
>
import
{
mapState
,
map
Action
s
}
from
'
vuex
'
;
import
{
mapState
,
map
Getter
s
}
from
'
vuex
'
;
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
panelResizer
from
'
~/vue_shared/components/panel_resizer.vue
'
;
import
skeletonLoadingContainer
from
'
~/vue_shared/components/skeleton_loading_container.vue
'
;
import
projectTree
from
'
./ide_project_tree.vue
'
;
import
ResizablePanel
from
'
./resizable_panel.vue
'
;
export
default
{
components
:
{
...
...
@@ -11,65 +12,27 @@
icon
,
panelResizer
,
skeletonLoadingContainer
,
},
data
()
{
return
{
width
:
290
,
};
ResizablePanel
,
},
computed
:
{
...
mapState
([
'
loading
'
,
'
projects
'
,
'
leftPanelCollapsed
'
,
]),
currentIcon
()
{
return
this
.
leftPanelCollapsed
?
'
angle-double-right
'
:
'
angle-double-left
'
;
},
maxSize
()
{
return
window
.
innerWidth
/
2
;
},
panelStyle
()
{
if
(
!
this
.
leftPanelCollapsed
)
{
return
{
width
:
`
${
this
.
width
}
px`
};
}
return
{};
},
showLoading
()
{
return
this
.
loading
;
},
},
methods
:
{
...
mapActions
([
'
setPanelCollapsedStatus
'
,
'
setResizingStatus
'
,
...
mapGetters
([
'
projectsWithTrees
'
,
]),
toggleCollapsed
()
{
this
.
setPanelCollapsedStatus
({
side
:
'
left
'
,
collapsed
:
!
this
.
leftPanelCollapsed
,
});
},
resizingStarted
()
{
this
.
setResizingStatus
(
true
);
},
resizingEnded
()
{
this
.
setResizingStatus
(
false
);
},
},
};
</
script
>
<
template
>
<div
class=
"multi-file-commit-panel"
:class=
"
{
'is-collapsed': leftPanelCollapsed,
}"
:style="panelStyle"
<resizable-panel
:collapsible=
"false"
:initial-width=
"290"
side=
"left"
>
<div
class=
"multi-file-commit-panel-inner"
>
<template
v-if=
"
showL
oading"
>
<template
v-if=
"
l
oading"
>
<div
class=
"multi-file-loading-container"
v-for=
"n in 3"
...
...
@@ -79,36 +42,10 @@
</div>
</
template
>
<project-tree
v-for=
"project in projects"
v-for=
"project in projects
WithTrees
"
:key=
"project.id"
:project=
"project"
/>
</div>
<button
type=
"button"
class=
"btn btn-transparent left-collapse-btn"
@
click=
"toggleCollapsed"
>
<icon
:name=
"currentIcon"
:size=
"18"
/>
<span
v-if=
"!leftPanelCollapsed"
class=
"collapse-text"
>
Collapse sidebar
</span>
</button>
<panel-resizer
:size.sync=
"width"
:enabled=
"!leftPanelCollapsed"
:start-size=
"290"
:min-size=
"200"
:max-size=
"maxSize"
@
resize-start=
"resizingStarted"
@
resize-end=
"resizingEnded"
side=
"right"
/>
</div>
</resizable-panel>
</template>
ee/app/assets/javascripts/ide/components/ide_status_bar.vue
Просмотр файла @
3551d6a3
<
script
>
import
{
mapState
}
from
'
vuex
'
;
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
tooltip
from
'
~/vue_shared/directives/tooltip
'
;
import
timeAgoMixin
from
'
~/vue_shared/mixins/timeago
'
;
...
...
@@ -20,11 +19,6 @@
required
:
true
,
},
},
computed
:
{
...
mapState
([
'
selectedFile
'
,
]),
},
};
</
script
>
...
...
@@ -35,32 +29,32 @@
name=
"branch"
:size=
"12"
/>
{{
selectedF
ile
.
branchId
}}
{{
f
ile
.
branchId
}}
</div>
<div>
<div
v-if=
"
selectedF
ile.lastCommit &&
selectedF
ile.lastCommit.id"
>
<div
v-if=
"
f
ile.lastCommit &&
f
ile.lastCommit.id"
>
Last commit:
<a
v-tooltip
:title=
"
selectedF
ile.lastCommit.message"
:href=
"
selectedF
ile.lastCommit.url"
:title=
"
f
ile.lastCommit.message"
:href=
"
f
ile.lastCommit.url"
>
{{
timeFormated
(
selectedF
ile
.
lastCommit
.
updatedAt
)
}}
by
{{
selectedF
ile
.
lastCommit
.
author
}}
{{
timeFormated
(
f
ile
.
lastCommit
.
updatedAt
)
}}
by
{{
f
ile
.
lastCommit
.
author
}}
</a>
</div>
</div>
<div
class=
"text-right"
>
{{
selectedF
ile
.
name
}}
{{
f
ile
.
name
}}
</div>
<div
class=
"text-right"
>
{{
selectedF
ile
.
eol
}}
{{
f
ile
.
eol
}}
</div>
<div
class=
"text-right"
>
{{
file
.
editorRow
}}
:
{{
file
.
editorColumn
}}
</div>
<div
class=
"text-right"
>
{{
selectedF
ile
.
fileLanguage
}}
{{
f
ile
.
fileLanguage
}}
</div>
</div>
</
template
>
ee/app/assets/javascripts/ide/components/new_branch_form.vue
удалено
100644 → 0
Просмотр файла @
a258b730
<
script
>
import
$
from
'
jquery
'
;
import
{
mapState
,
mapActions
}
from
'
vuex
'
;
import
flash
,
{
hideFlash
}
from
'
~/flash
'
;
import
loadingIcon
from
'
~/vue_shared/components/loading_icon.vue
'
;
export
default
{
components
:
{
loadingIcon
,
},
data
()
{
return
{
branchName
:
''
,
loading
:
false
,
};
},
computed
:
{
...
mapState
([
'
currentBranch
'
,
]),
btnDisabled
()
{
return
this
.
loading
||
this
.
branchName
===
''
;
},
},
created
()
{
// Dropdown is outside of Vue instance & is controlled by Bootstrap
this
.
$dropdown
=
$
(
'
.git-revision-dropdown
'
);
// text element is outside Vue app
this
.
dropdownText
=
document
.
querySelector
(
'
.project-refs-form .dropdown-toggle-text
'
);
},
methods
:
{
...
mapActions
([
'
createNewBranch
'
,
]),
toggleDropdown
()
{
this
.
$dropdown
.
dropdown
(
'
toggle
'
);
},
submitNewBranch
()
{
// need to query as the element is appended outside of Vue
const
flashEl
=
this
.
$refs
.
flashContainer
.
querySelector
(
'
.flash-alert
'
);
this
.
loading
=
true
;
if
(
flashEl
)
{
hideFlash
(
flashEl
,
false
);
}
this
.
createNewBranch
(
this
.
branchName
)
.
then
(()
=>
{
this
.
loading
=
false
;
this
.
branchName
=
''
;
if
(
this
.
dropdownText
)
{
this
.
dropdownText
.
textContent
=
this
.
currentBranchId
;
}
this
.
toggleDropdown
();
})
.
catch
(
res
=>
res
.
json
().
then
((
data
)
=>
{
this
.
loading
=
false
;
flash
(
data
.
message
,
'
alert
'
,
this
.
$el
);
}));
},
},
};
</
script
>
<
template
>
<div>
<div
class=
"flash-container"
ref=
"flashContainer"
>
</div>
<p>
Create from:
<code>
{{
currentBranch
}}
</code>
</p>
<input
class=
"form-control js-new-branch-name"
type=
"text"
placeholder=
"Name new branch"
v-model=
"branchName"
@
keyup.enter.stop.prevent=
"submitNewBranch"
/>
<div
class=
"prepend-top-default clearfix"
>
<button
type=
"button"
class=
"btn btn-primary pull-left"
:disabled=
"btnDisabled"
@
click.stop.prevent=
"submitNewBranch"
>
<loading-icon
v-if=
"loading"
:inline=
"true"
/>
<span>
Create
</span>
</button>
<button
type=
"button"
class=
"btn btn-default pull-right"
@
click.stop.prevent=
"toggleDropdown"
>
Cancel
</button>
</div>
</div>
</
template
>
ee/app/assets/javascripts/ide/components/new_dropdown/index.vue
Просмотр файла @
3551d6a3
<
script
>
import
{
mapActions
}
from
'
vuex
'
;
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
newModal
from
'
./modal.vue
'
;
import
upload
from
'
./upload.vue
'
;
...
...
@@ -18,10 +19,6 @@
type
:
String
,
required
:
true
,
},
parent
:
{
type
:
Object
,
default
:
null
,
},
},
data
()
{
return
{
...
...
@@ -31,6 +28,9 @@
};
},
methods
:
{
...
mapActions
([
'
createTempEntry
'
,
]),
createNewItem
(
type
)
{
this
.
modalType
=
type
;
this
.
openModal
=
true
;
...
...
@@ -85,7 +85,7 @@
<upload
:branch-id=
"branch"
:path=
"path"
:parent=
"parent
"
@
create=
"createTempEntry
"
/>
</li>
<li>
...
...
@@ -104,8 +104,8 @@
:type=
"modalType"
:branch-id=
"branch"
:path=
"path"
:parent=
"parent"
@
hide=
"hideModal"
@
create=
"createTempEntry"
/>
</div>
</
template
>
ee/app/assets/javascripts/ide/components/new_dropdown/modal.vue
Просмотр файла @
3551d6a3
<
script
>
import
{
mapActions
,
mapState
}
from
'
vuex
'
;
import
{
__
}
from
'
~/locale
'
;
import
modal
from
'
~/vue_shared/components/modal.vue
'
;
...
...
@@ -12,10 +11,6 @@
type
:
String
,
required
:
true
,
},
parent
:
{
type
:
Object
,
default
:
null
,
},
type
:
{
type
:
String
,
required
:
true
,
...
...
@@ -31,9 +26,6 @@
};
},
computed
:
{
...
mapState
([
'
currentProjectId
'
,
]),
modalTitle
()
{
if
(
this
.
type
===
'
tree
'
)
{
return
__
(
'
Create new directory
'
);
...
...
@@ -60,15 +52,10 @@
this
.
$refs
.
fieldName
.
focus
();
},
methods
:
{
...
mapActions
([
'
createTempEntry
'
,
]),
createEntryInStore
()
{
this
.
createTempEntry
({
projectId
:
this
.
currentProjectId
,
this
.
$emit
(
'
create
'
,
{
branchId
:
this
.
branchId
,
parent
:
this
.
parent
,
name
:
this
.
entryName
.
replace
(
new
RegExp
(
`^
${
this
.
path
}
/`
),
''
),
name
:
this
.
entryName
,
type
:
this
.
type
,
});
...
...
ee/app/assets/javascripts/ide/components/new_dropdown/upload.vue
Просмотр файла @
3551d6a3
<
script
>
import
{
mapActions
,
mapState
}
from
'
vuex
'
;
export
default
{
props
:
{
branchId
:
{
type
:
String
,
required
:
true
,
},
parent
:
{
type
:
Object
,
default
:
null
,
path
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
},
computed
:
{
...
mapState
([
'
trees
'
,
'
currentProjectId
'
,
]),
},
mounted
()
{
this
.
$refs
.
fileUpload
.
addEventListener
(
'
change
'
,
this
.
openFile
);
},
...
...
@@ -25,9 +18,6 @@
this
.
$refs
.
fileUpload
.
removeEventListener
(
'
change
'
,
this
.
openFile
);
},
methods
:
{
...
mapActions
([
'
createTempEntry
'
,
]),
createFile
(
target
,
file
,
isText
)
{
const
{
name
}
=
file
;
let
{
result
}
=
target
;
...
...
@@ -36,11 +26,9 @@
result
=
result
.
split
(
'
base64,
'
)[
1
];
}
this
.
createTempEntry
({
name
,
projectId
:
this
.
currentProjectId
,
this
.
$emit
(
'
create
'
,
{
name
:
`
${(
this
.
path
?
`
${
this
.
path
}
/`
:
''
)}${
name
}
`
,
branchId
:
this
.
branchId
,
parent
:
this
.
parent
,
type
:
'
blob
'
,
content
:
result
,
base64
:
!
isText
,
...
...
ee/app/assets/javascripts/ide/components/repo_commit_section.vue
Просмотр файла @
3551d6a3
...
...
@@ -53,7 +53,6 @@ export default {
},
methods
:
{
...
mapActions
([
'
getTreeData
'
,
'
setPanelCollapsedStatus
'
,
]),
...
mapActions
(
'
commit
'
,
[
...
...
ee/app/assets/javascripts/ide/components/repo_edit_button.vue
удалено
100644 → 0
Просмотр файла @
a258b730
<
script
>
import
{
mapGetters
,
mapActions
,
mapState
}
from
'
vuex
'
;
import
modal
from
'
~/vue_shared/components/modal.vue
'
;
export
default
{
components
:
{
modal
,
},
computed
:
{
...
mapState
([
'
editMode
'
,
]),
...
mapGetters
([
'
canEditFile
'
,
]),
buttonLabel
()
{
return
this
.
editMode
?
this
.
__
(
'
Cancel edit
'
)
:
this
.
__
(
'
Edit
'
);
},
},
methods
:
{
...
mapActions
([
'
toggleEditMode
'
,
]),
},
};
</
script
>
<
template
>
<div
class=
"editable-mode"
>
<button
v-if=
"canEditFile"
class=
"btn btn-default"
type=
"button"
@
click.prevent=
"toggleEditMode()"
>
<i
v-if=
"!editMode"
class=
"fa fa-pencil"
aria-hidden=
"true"
>
</i>
<span>
{{
buttonLabel
}}
</span>
</button>
</div>
</
template
>
ee/app/assets/javascripts/ide/components/repo_editor.vue
Просмотр файла @
3551d6a3
<
script
>
/* global monaco */
import
{
mapState
,
mapGetters
,
mapActions
}
from
'
vuex
'
;
import
{
mapState
,
mapActions
}
from
'
vuex
'
;
import
flash
from
'
~/flash
'
;
import
monacoLoader
from
'
../monaco_loader
'
;
import
Editor
from
'
../lib/editor
'
;
export
default
{
props
:
{
file
:
{
type
:
Object
,
required
:
true
,
},
},
computed
:
{
...
mapGetters
([
'
activeFile
'
,
'
activeFileExtension
'
,
]),
...
mapState
([
'
leftPanelCollapsed
'
,
'
rightPanelCollapsed
'
,
'
panelResizing
'
,
'
viewer
'
,
'
delayViewerUpdated
'
,
]),
shouldHideEditor
()
{
return
this
.
activeF
ile
&&
this
.
activeF
ile
.
binary
&&
!
this
.
activeF
ile
.
raw
;
return
this
.
f
ile
&&
this
.
f
ile
.
binary
&&
!
this
.
f
ile
.
raw
;
},
},
watch
:
{
activeF
ile
(
oldVal
,
newVal
)
{
if
(
newVal
&&
!
newVal
.
active
)
{
f
ile
(
oldVal
,
newVal
)
{
if
(
newVal
.
path
!==
this
.
file
.
path
)
{
this
.
initMonaco
();
}
},
...
...
@@ -34,11 +35,6 @@ export default {
rightPanelCollapsed
()
{
this
.
editor
.
updateDimensions
();
},
panelResizing
(
isResizing
)
{
if
(
isResizing
===
false
)
{
this
.
editor
.
updateDimensions
();
}
},
viewer
()
{
this
.
createEditorInstance
();
},
...
...
@@ -72,7 +68,7 @@ export default {
this
.
editor
.
clearEditor
();
this
.
getRawFileData
(
this
.
activeF
ile
)
this
.
getRawFileData
(
this
.
f
ile
)
.
then
(()
=>
{
const
viewerPromise
=
this
.
delayViewerUpdated
?
this
.
updateViewer
(
'
editor
'
)
:
Promise
.
resolve
();
...
...
@@ -101,9 +97,9 @@ export default {
});
},
setupEditor
()
{
if
(
!
this
.
activeF
ile
||
!
this
.
editor
.
instance
)
return
;
if
(
!
this
.
f
ile
||
!
this
.
editor
.
instance
)
return
;
this
.
model
=
this
.
editor
.
createModel
(
this
.
activeF
ile
);
this
.
model
=
this
.
editor
.
createModel
(
this
.
f
ile
);
this
.
editor
.
attachModel
(
this
.
model
);
...
...
@@ -112,7 +108,7 @@ export default {
if
(
file
.
active
)
{
this
.
changeFileContent
({
file
,
path
:
file
.
path
,
content
:
model
.
getModel
().
getValue
(),
});
}
...
...
@@ -127,8 +123,8 @@ export default {
});
this
.
editor
.
setPosition
({
lineNumber
:
this
.
activeF
ile
.
editorRow
,
column
:
this
.
activeF
ile
.
editorColumn
,
lineNumber
:
this
.
f
ile
.
editorRow
,
column
:
this
.
f
ile
.
editorColumn
,
});
// Handle File Language
...
...
@@ -152,7 +148,7 @@ export default {
>
<div
v-if=
"shouldHideEditor"
v-html=
"
activeF
ile.html"
v-html=
"
f
ile.html"
>
</div>
<div
...
...
ee/app/assets/javascripts/ide/components/repo_file.vue
Просмотр файла @
3551d6a3
<
script
>
import
{
mapActions
,
mapState
}
from
'
vuex
'
;
import
{
mapActions
}
from
'
vuex
'
;
import
skeletonLoadingContainer
from
'
~/vue_shared/components/skeleton_loading_container.vue
'
;
import
fileIcon
from
'
~/vue_shared/components/file_icon.vue
'
;
import
router
from
'
../ide_router
'
;
import
newDropdown
from
'
./new_dropdown/index.vue
'
;
import
fileStatusIcon
from
'
./repo_file_status_icon.vue
'
;
import
changedFileIcon
from
'
./changed_file_icon.vue
'
;
import
timeAgoMixin
from
'
~/vue_shared/mixins/timeago
'
;
import
skeletonLoadingContainer
from
'
~/vue_shared/components/skeleton_loading_container.vue
'
;
import
fileIcon
from
'
~/vue_shared/components/file_icon.vue
'
;
import
newDropdown
from
'
./new_dropdown/index.vue
'
;
import
fileStatusIcon
from
'
ee/ide/components/repo_file_status_icon.vue
'
;
// eslint-disable-line import/first
import
changedFileIcon
from
'
ee/ide/components/changed_file_icon.vue
'
;
// eslint-disable-line import/first
export
default
{
name
:
'
RepoFile
'
,
components
:
{
skeletonLoadingContainer
,
newDropdown
,
fileStatusIcon
,
fileIcon
,
changedFileIcon
,
export
default
{
name
:
'
RepoFile
'
,
components
:
{
skeletonLoadingContainer
,
newDropdown
,
fileStatusIcon
,
fileIcon
,
changedFileIcon
,
},
props
:
{
file
:
{
type
:
Object
,
required
:
true
,
},
mixins
:
[
timeAgoMixin
,
],
props
:
{
file
:
{
type
:
Object
,
required
:
true
,
},
showExtraColumns
:
{
type
:
Boolean
,
default
:
false
,
},
level
:
{
type
:
Number
,
required
:
true
,
},
computed
:
{
...
mapState
([
'
leftPanelCollapsed
'
,
]),
isSubmodule
()
{
return
this
.
file
.
type
===
'
submodule
'
;
},
isTree
()
{
return
this
.
file
.
type
===
'
tree
'
;
},
levelIndentation
()
{
if
(
this
.
file
.
level
>
0
)
{
return
{
marginLeft
:
`
${
this
.
file
.
level
*
16
}
px`
,
};
}
return
{};
},
shortId
()
{
return
this
.
file
.
id
.
substr
(
0
,
8
);
},
fileClass
()
{
if
(
this
.
file
.
type
===
'
blob
'
)
{
if
(
this
.
file
.
active
)
{
return
'
file-open file-active
'
;
}
return
this
.
file
.
opened
?
'
file-open
'
:
''
;
}
else
if
(
this
.
file
.
type
===
'
tree
'
)
{
return
'
folder
'
;
}
return
''
;
},
},
computed
:
{
isTree
()
{
return
this
.
file
.
type
===
'
tree
'
;
},
updated
()
{
if
(
this
.
file
.
type
===
'
blob
'
&&
this
.
file
.
active
)
{
this
.
$el
.
scrollIntoView
();
}
isBlob
()
{
return
this
.
file
.
type
===
'
blob
'
;
},
levelIndentation
()
{
return
{
marginLeft
:
`
${
this
.
level
*
16
}
px`
,
};
},
methods
:
{
...
mapActions
([
'
updateDelayViewerUpdated
'
,
]),
clickFile
(
row
)
{
// Manual Action if a tree is selected/opened
if
(
this
.
file
.
type
===
'
tree
'
&&
this
.
$router
.
currentRoute
.
path
===
`/project
${
row
.
url
}
`
)
{
this
.
$store
.
dispatch
(
'
toggleTreeOpen
'
,
{
endpoint
:
this
.
file
.
url
,
tree
:
this
.
file
,
});
}
fileClass
()
{
return
{
'
file-open
'
:
this
.
isBlob
&&
this
.
file
.
opened
,
'
file-active
'
:
this
.
isBlob
&&
this
.
file
.
active
,
folder
:
this
.
isTree
,
};
},
},
updated
()
{
if
(
this
.
file
.
type
===
'
blob
'
&&
this
.
file
.
active
)
{
this
.
$el
.
scrollIntoView
();
}
},
methods
:
{
...
mapActions
([
'
toggleTreeOpen
'
,
'
updateDelayViewerUpdated
'
]),
clickFile
()
{
// Manual Action if a tree is selected/opened
if
(
this
.
isTree
&&
this
.
$router
.
currentRoute
.
path
===
`/project
${
this
.
file
.
url
}
`
)
{
this
.
toggleTreeOpen
(
this
.
file
.
path
);
}
const
delayPromise
=
this
.
file
.
changed
?
Promise
.
resolve
()
:
this
.
updateDelayViewerUpdated
(
true
);
const
delayPromise
=
this
.
file
.
changed
?
Promise
.
resolve
()
:
this
.
updateDelayViewerUpdated
(
true
);
return
delayPromise
.
then
(()
=>
{
this
.
$router
.
push
(
`/project
${
row
.
url
}
`
);
});
},
return
delayPromise
.
then
(()
=>
{
router
.
push
(
`/project
${
this
.
file
.
url
}
`
);
});
},
};
},
};
</
script
>
<
template
>
...
...
@@ -101,54 +82,45 @@
>
<div
class=
"file-name"
@
click=
"clickFile(file)"
@
click=
"clickFile"
role=
"button"
>
<
a
<
span
class=
"ide-file-name str-truncated"
:style=
"levelIndentation"
>
<file-icon
:file-name=
"file.name"
:loading=
"file.loading"
:folder=
"
file.type === 't
ree
'
"
:folder=
"
isT
ree"
:opened=
"file.opened"
:style=
"levelIndentation"
:size=
"16"
/>
{{
file
.
name
}}
<file-status-icon
:file=
"file"
/>
</a>
<file-status-icon
:file=
"file"
/>
</span>
<changed-file-icon
:file=
"file"
v-if=
"file.changed || file.tempFile"
class=
"prepend-top-5 pull-right"
/>
<new-dropdown
v-if=
"isTree"
:project-id=
"file.projectId"
:branch=
"file.branchId"
:path=
"file.path"
:parent=
"file"
/>
<changed-file-icon
:file=
"file"
v-if=
"file.changed || file.tempFile"
class=
"prepend-top-5"
class=
"pull-right prepend-left-8"
/>
<template
v-if=
"isSubmodule && file.id"
>
@
<span
class=
"commit-sha"
>
<a
@
click.stop
:href=
"file.tree_url"
>
{{
shortId
}}
</a>
</span>
</
template
>
</div>
</div>
<
template
v-if=
"file.opened"
>
<template
v-if=
"file.opened"
>
<repo-file
v-for=
"childFile in file.tree"
:key=
"childFile.key"
:file=
"childFile"
:level=
"level + 1"
/>
</
template
>
</div>
...
...
ee/app/assets/javascripts/ide/components/repo_file_buttons.vue
Просмотр файла @
3551d6a3
<
script
>
import
{
mapGetters
}
from
'
vuex
'
;
export
default
{
props
:
{
file
:
{
type
:
Object
,
required
:
true
,
},
},
computed
:
{
...
mapGetters
([
'
activeFile
'
,
]),
showButtons
()
{
return
this
.
activeF
ile
.
rawPath
||
this
.
activeF
ile
.
blamePath
||
this
.
activeF
ile
.
commitsPath
||
this
.
activeF
ile
.
permalink
;
return
this
.
f
ile
.
rawPath
||
this
.
f
ile
.
blamePath
||
this
.
f
ile
.
commitsPath
||
this
.
f
ile
.
permalink
;
},
rawDownloadButtonLabel
()
{
return
this
.
activeF
ile
.
binary
?
'
Download
'
:
'
Raw
'
;
return
this
.
f
ile
.
binary
?
'
Download
'
:
'
Raw
'
;
},
},
};
...
...
@@ -25,7 +26,7 @@ export default {
class=
"multi-file-editor-btn-group"
>
<a
:href=
"
activeF
ile.rawPath"
:href=
"
f
ile.rawPath"
target=
"_blank"
class=
"btn btn-default btn-sm raw"
rel=
"noopener noreferrer"
>
...
...
@@ -38,19 +39,19 @@ export default {
aria-label=
"File actions"
>
<a
:href=
"
activeF
ile.blamePath"
:href=
"
f
ile.blamePath"
class=
"btn btn-default btn-sm blame"
>
Blame
</a>
<a
:href=
"
activeF
ile.commitsPath"
:href=
"
f
ile.commitsPath"
class=
"btn btn-default btn-sm history"
>
History
</a>
<a
:href=
"
activeF
ile.permalink"
:href=
"
f
ile.permalink"
class=
"btn btn-default btn-sm permalink"
>
Permalink
...
...
ee/app/assets/javascripts/ide/components/repo_preview.vue
удалено
100644 → 0
Просмотр файла @
a258b730
<
script
>
import
$
from
'
jquery
'
;
import
{
mapGetters
}
from
'
vuex
'
;
import
LineHighlighter
from
'
~/line_highlighter
'
;
import
syntaxHighlight
from
'
~/syntax_highlight
'
;
export
default
{
computed
:
{
...
mapGetters
([
'
activeFile
'
,
]),
renderErrorTooLarge
()
{
return
this
.
activeFile
.
renderError
===
'
too_large
'
;
},
},
mounted
()
{
this
.
highlightFile
();
this
.
lineHighlighter
=
new
LineHighlighter
({
fileHolderSelector
:
'
.blob-viewer-container
'
,
scrollFileHolder
:
true
,
});
},
updated
()
{
this
.
$nextTick
(()
=>
{
this
.
highlightFile
();
});
},
methods
:
{
highlightFile
()
{
syntaxHighlight
(
$
(
this
.
$el
).
find
(
'
.file-content
'
));
},
},
};
</
script
>
<
template
>
<div>
<div
v-if=
"!activeFile.renderError"
v-html=
"activeFile.html"
class=
"multi-file-preview-holder"
>
</div>
<div
v-else-if=
"activeFile.tempFile"
class=
"vertical-center render-error"
>
<p
class=
"text-center"
>
The source could not be displayed for this temporary file.
</p>
</div>
<div
v-else-if=
"renderErrorTooLarge"
class=
"vertical-center render-error"
>
<p
class=
"text-center"
>
The source could not be displayed because it is too large.
You can
<a
:href=
"activeFile.rawPath"
download
>
download
</a>
it instead.
</p>
</div>
<div
v-else
class=
"vertical-center render-error"
>
<p
class=
"text-center"
>
The source could not be displayed because a rendering error occurred.
You can
<a
:href=
"activeFile.rawPath"
download
>
download
</a>
it instead.
</p>
</div>
</div>
</
template
>
ee/app/assets/javascripts/ide/components/repo_tab.vue
Просмотр файла @
3551d6a3
...
...
@@ -67,7 +67,7 @@
<button
type=
"button"
class=
"multi-file-tab-close"
@
click.stop.prevent=
"closeFile(tab)"
@
click.stop.prevent=
"closeFile(tab
.path
)"
:aria-label=
"closeLabel"
>
<icon
...
...
ee/app/assets/javascripts/ide/components/repo_tabs.vue
Просмотр файла @
3551d6a3
<
script
>
import
{
mapActions
,
mapGetters
,
mapState
}
from
'
vuex
'
;
import
{
mapActions
}
from
'
vuex
'
;
import
RepoTab
from
'
./repo_tab.vue
'
;
import
EditorMode
from
'
./editor_mode_dropdown.vue
'
;
...
...
@@ -8,29 +8,33 @@
RepoTab
,
EditorMode
,
},
props
:
{
files
:
{
type
:
Array
,
required
:
true
,
},
viewer
:
{
type
:
String
,
required
:
true
,
},
hasChanges
:
{
type
:
Boolean
,
required
:
true
,
},
},
data
()
{
return
{
showShadow
:
false
,
};
},
computed
:
{
...
mapGetters
([
'
hasChanges
'
,
]),
...
mapState
([
'
openFiles
'
,
'
viewer
'
,
]),
},
updated
()
{
if
(
!
this
.
$refs
.
tabsScroller
)
return
;
this
.
showShadow
=
this
.
$refs
.
tabsScroller
.
scrollWidth
>
this
.
$refs
.
tabsScroller
.
offsetWidth
;
this
.
showShadow
=
this
.
$refs
.
tabsScroller
.
scrollWidth
>
this
.
$refs
.
tabsScroller
.
offsetWidth
;
},
methods
:
{
...
mapActions
([
'
updateViewer
'
,
]),
...
mapActions
([
'
updateViewer
'
]),
},
};
</
script
>
...
...
@@ -42,7 +46,7 @@
ref=
"tabsScroller"
>
<repo-tab
v-for=
"tab in
openF
iles"
v-for=
"tab in
f
iles"
:key=
"tab.key"
:tab=
"tab"
/>
...
...
Пред
1
2
3
4
След
Редактирование
Предварительный просмотр
Поддерживает Markdown
0%
Попробовать снова
или
прикрепить новый файл
.
Отмена
You are about to add
0
people
to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Отмена
Пожалуйста,
зарегистрируйтесь
или
войдите
чтобы прокомментировать