debian-mirror-gitlab/app/assets/javascripts/ide/components/repo_editor.vue

279 lines
6.9 KiB
Vue
Raw Normal View History

2018-05-09 12:01:36 +05:30
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
import flash from '~/flash';
import ContentViewer from '~/vue_shared/components/content_viewer/content_viewer.vue';
2018-11-08 19:23:39 +05:30
import DiffViewer from '~/vue_shared/components/diff_viewer/diff_viewer.vue';
2018-10-15 14:42:47 +05:30
import { activityBarViews, viewerTypes } from '../constants';
2018-05-09 12:01:36 +05:30
import Editor from '../lib/editor';
2018-11-08 19:23:39 +05:30
import ExternalLink from './external_link.vue';
2018-05-09 12:01:36 +05:30
export default {
components: {
ContentViewer,
2018-11-08 19:23:39 +05:30
DiffViewer,
ExternalLink,
2018-05-09 12:01:36 +05:30
},
props: {
file: {
type: Object,
required: true,
},
},
computed: {
2018-11-08 19:23:39 +05:30
...mapState([
'rightPanelCollapsed',
'viewer',
'panelResizing',
'currentActivityView',
'rightPane',
]),
2018-10-15 14:42:47 +05:30
...mapGetters([
'currentMergeRequest',
'getStagedFile',
'isEditModeActive',
'isCommitModeActive',
'isReviewModeActive',
]),
2018-05-09 12:01:36 +05:30
shouldHideEditor() {
return this.file && this.file.binary && !this.file.content;
},
2018-11-08 19:23:39 +05:30
showContentViewer() {
return (
(this.shouldHideEditor || this.file.viewMode === 'preview') &&
(this.viewer !== viewerTypes.mr || !this.file.mrChange)
);
},
showDiffViewer() {
return this.shouldHideEditor && this.file.mrChange && this.viewer === viewerTypes.mr;
},
2018-05-09 12:01:36 +05:30
editTabCSS() {
return {
2018-11-08 19:23:39 +05:30
active: this.file.viewMode === 'editor',
2018-05-09 12:01:36 +05:30
};
},
previewTabCSS() {
return {
active: this.file.viewMode === 'preview',
};
},
},
watch: {
2018-10-15 14:42:47 +05:30
file(newVal, oldVal) {
if (oldVal.pending) {
this.removePendingTab(oldVal);
}
2018-05-09 12:01:36 +05:30
// Compare key to allow for files opened in review mode to be cached differently
2018-10-15 14:42:47 +05:30
if (oldVal.key !== this.file.key) {
2018-11-08 19:23:39 +05:30
this.initEditor();
2018-10-15 14:42:47 +05:30
if (this.currentActivityView !== activityBarViews.edit) {
this.setFileViewMode({
file: this.file,
2018-11-08 19:23:39 +05:30
viewMode: 'editor',
2018-10-15 14:42:47 +05:30
});
}
}
},
currentActivityView() {
if (this.currentActivityView !== activityBarViews.edit) {
this.setFileViewMode({
file: this.file,
2018-11-08 19:23:39 +05:30
viewMode: 'editor',
2018-10-15 14:42:47 +05:30
});
2018-05-09 12:01:36 +05:30
}
},
rightPanelCollapsed() {
this.editor.updateDimensions();
},
viewer() {
2018-11-18 11:00:15 +05:30
if (!this.file.pending) {
this.createEditorInstance();
}
2018-05-09 12:01:36 +05:30
},
panelResizing() {
if (!this.panelResizing) {
this.editor.updateDimensions();
}
},
2018-11-08 19:23:39 +05:30
rightPane() {
this.editor.updateDimensions();
},
2018-05-09 12:01:36 +05:30
},
beforeDestroy() {
this.editor.dispose();
},
mounted() {
2018-11-08 19:23:39 +05:30
if (!this.editor) {
this.editor = Editor.create();
2018-05-09 12:01:36 +05:30
}
2018-11-08 19:23:39 +05:30
this.initEditor();
2018-05-09 12:01:36 +05:30
},
methods: {
...mapActions([
2018-11-18 11:00:15 +05:30
'getFileData',
2018-05-09 12:01:36 +05:30
'getRawFileData',
'changeFileContent',
'setFileLanguage',
'setEditorPosition',
'setFileViewMode',
'setFileEOL',
'updateViewer',
2018-10-15 14:42:47 +05:30
'removePendingTab',
2018-05-09 12:01:36 +05:30
]),
2018-11-08 19:23:39 +05:30
initEditor() {
2018-05-09 12:01:36 +05:30
if (this.shouldHideEditor) return;
this.editor.clearEditor();
2018-11-18 11:00:15 +05:30
this.getFileData({
2018-05-09 12:01:36 +05:30
path: this.file.path,
2018-11-18 11:00:15 +05:30
makeFileActive: false,
2018-05-09 12:01:36 +05:30
})
2018-11-18 11:00:15 +05:30
.then(() =>
this.getRawFileData({
path: this.file.path,
}),
)
2018-05-09 12:01:36 +05:30
.then(() => {
this.createEditorInstance();
})
.catch(err => {
2018-11-08 19:23:39 +05:30
flash('Error setting up editor. Please try again.', 'alert', document, null, false, true);
2018-05-09 12:01:36 +05:30
throw err;
});
},
createEditorInstance() {
this.editor.dispose();
this.$nextTick(() => {
2018-10-15 14:42:47 +05:30
if (this.viewer === viewerTypes.edit) {
2018-05-09 12:01:36 +05:30
this.editor.createInstance(this.$refs.editor);
} else {
2018-10-15 14:42:47 +05:30
this.editor.createDiffInstance(this.$refs.editor, !this.isReviewModeActive);
2018-05-09 12:01:36 +05:30
}
this.setupEditor();
});
},
setupEditor() {
if (!this.file || !this.editor.instance) return;
2018-10-15 14:42:47 +05:30
const head = this.getStagedFile(this.file.path);
this.model = this.editor.createModel(
this.file,
this.file.staged && this.file.key.indexOf('unstaged-') === 0 ? head : null,
);
2018-05-09 12:01:36 +05:30
2018-10-15 14:42:47 +05:30
if (this.viewer === viewerTypes.mr && this.file.mrChange) {
2018-05-09 12:01:36 +05:30
this.editor.attachMergeRequestModel(this.model);
} else {
this.editor.attachModel(this.model);
}
this.model.onChange(model => {
const { file } = model;
if (file.active) {
this.changeFileContent({
path: file.path,
content: model.getModel().getValue(),
});
}
});
// Handle Cursor Position
this.editor.onPositionChange((instance, e) => {
this.setEditorPosition({
editorRow: e.position.lineNumber,
editorColumn: e.position.column,
});
});
this.editor.setPosition({
lineNumber: this.file.editorRow,
column: this.file.editorColumn,
});
// Handle File Language
this.setFileLanguage({
fileLanguage: this.model.language,
});
// Get File eol
this.setFileEOL({
eol: this.model.eol,
});
},
},
2018-10-15 14:42:47 +05:30
viewerTypes,
2018-05-09 12:01:36 +05:30
};
</script>
<template>
<div
id="ide"
class="blob-viewer-container blob-editor-container"
>
2018-10-15 14:42:47 +05:30
<div class="ide-mode-tabs clearfix" >
2018-05-09 12:01:36 +05:30
<ul
2018-10-15 14:42:47 +05:30
v-if="!shouldHideEditor && isEditModeActive"
2018-11-08 19:23:39 +05:30
class="nav-links float-left"
2018-10-15 14:42:47 +05:30
>
2018-05-09 12:01:36 +05:30
<li :class="editTabCSS">
<a
href="javascript:void(0);"
role="button"
2018-11-08 19:23:39 +05:30
@click.prevent="setFileViewMode({ file, viewMode: 'editor' })">
2018-10-15 14:42:47 +05:30
<template v-if="viewer === $options.viewerTypes.edit">
2018-05-09 12:01:36 +05:30
{{ __('Edit') }}
</template>
<template v-else>
{{ __('Review') }}
</template>
</a>
</li>
<li
v-if="file.previewMode"
:class="previewTabCSS">
<a
href="javascript:void(0);"
role="button"
@click.prevent="setFileViewMode({ file, viewMode:'preview' })">
{{ file.previewMode.previewTitle }}
</a>
</li>
</ul>
2018-11-08 19:23:39 +05:30
<external-link
2018-05-09 12:01:36 +05:30
:file="file"
/>
</div>
<div
2018-11-08 19:23:39 +05:30
v-show="!shouldHideEditor && file.viewMode ==='editor'"
2018-05-09 12:01:36 +05:30
ref="editor"
2018-10-15 14:42:47 +05:30
:class="{
'is-readonly': isCommitModeActive,
2018-11-18 11:00:15 +05:30
'is-deleted': file.deleted,
'is-added': file.tempFile
2018-10-15 14:42:47 +05:30
}"
2018-11-08 19:23:39 +05:30
class="multi-file-editor-holder"
2018-05-09 12:01:36 +05:30
>
</div>
<content-viewer
2018-11-08 19:23:39 +05:30
v-if="showContentViewer"
2018-05-09 12:01:36 +05:30
:content="file.content || file.raw"
:path="file.rawPath || file.path"
:file-size="file.size"
:project-path="file.projectId"/>
2018-11-08 19:23:39 +05:30
<diff-viewer
v-if="showDiffViewer"
:diff-mode="file.mrChange.diffMode"
:new-path="file.mrChange.new_path"
:new-sha="currentMergeRequest.sha"
:old-path="file.mrChange.old_path"
:old-sha="currentMergeRequest.baseCommitSha"
:project-path="file.projectId"/>
2018-05-09 12:01:36 +05:30
</div>
</template>