summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2018-05-04 13:40:41 +0100
committerPhil Hughes <me@iamphill.com>2018-05-04 13:40:41 +0100
commit80617b9039ccbeeec07e299e41690be6ce2d95ec (patch)
treedc34efce00b956309c147ea59a786b58b47805b6 /app/assets
parentcb8682b841b92cb6f97906bb9289ccbb13f2f31e (diff)
parentd9f3af500c1c3135a63014904459e5a4ab6bc395 (diff)
downloadgitlab-ce-80617b9039ccbeeec07e299e41690be6ce2d95ec.tar.gz
Merge branch '44846-improve-web-ide-left-panel-and-modes' into ide-sidebar-commit-box
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/environments/components/container.vue1
-rw-r--r--app/assets/javascripts/ide/components/changed_file_icon.vue10
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/form.vue2
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/list_item.vue2
-rw-r--r--app/assets/javascripts/ide/components/repo_file.vue89
-rw-r--r--app/assets/javascripts/ide/stores/getters.js21
-rw-r--r--app/assets/javascripts/ide/stores/utils.js10
-rw-r--r--app/assets/javascripts/sidebar/components/participants/participants.vue4
-rw-r--r--app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions.vue8
-rw-r--r--app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue22
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.js15
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue18
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue4
-rw-r--r--app/assets/stylesheets/pages/boards.scss2
-rw-r--r--app/assets/stylesheets/pages/repo.scss14
15 files changed, 166 insertions, 56 deletions
diff --git a/app/assets/javascripts/environments/components/container.vue b/app/assets/javascripts/environments/components/container.vue
index dbee81fa320..6bd7c6b49cb 100644
--- a/app/assets/javascripts/environments/components/container.vue
+++ b/app/assets/javascripts/environments/components/container.vue
@@ -43,6 +43,7 @@
<div class="environments-container">
<loading-icon
+ class="prepend-top-default"
label="Loading environments"
v-if="isLoading"
size="3"
diff --git a/app/assets/javascripts/ide/components/changed_file_icon.vue b/app/assets/javascripts/ide/components/changed_file_icon.vue
index fdbc14a4b8f..1cec84706fc 100644
--- a/app/assets/javascripts/ide/components/changed_file_icon.vue
+++ b/app/assets/javascripts/ide/components/changed_file_icon.vue
@@ -43,7 +43,7 @@ export default {
return `${this.changedIcon}-solid`;
},
changedIconClass() {
- return `multi-${this.changedIcon} prepend-left-5 pull-left`;
+ return `multi-${this.changedIcon} pull-left`;
},
tooltipTitle() {
if (!this.showTooltip) return undefined;
@@ -79,13 +79,7 @@ export default {
class="ide-file-changed-icon"
>
<icon
- v-if="file.staged && showStagedIcon"
- :name="stagedIcon"
- :size="12"
- :css-classes="changedIconClass"
- />
- <icon
- v-if="file.changed || file.tempFile || (file.staged && !showStagedIcon)"
+ v-if="file.changed || file.tempFile || file.staged"
:name="changedIcon"
:size="12"
:css-classes="changedIconClass"
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/form.vue b/app/assets/javascripts/ide/components/commit_sidebar/form.vue
index 0031add101e..163b21221df 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/form.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/form.vue
@@ -23,7 +23,7 @@ export default {
computed: {
...mapState(['changedFiles', 'stagedFiles', 'currentActivityView', 'lastCommitMsg']),
...mapState('commit', ['commitMessage', 'submitCommitLoading']),
- ...mapGetters(['hasChanges', 'someUncommitedChanges']),
+ ...mapGetters(['hasChanges']),
...mapGetters('commit', ['commitButtonDisabled', 'discardDraftButtonDisabled']),
overviewText() {
return sprintf(
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
index ad4713c40d5..872302840e2 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
@@ -36,7 +36,7 @@ export default {
return this.file.tempFile ? `file-addition${prefix}` : `file-modified${prefix}`;
},
iconClass() {
- return `multi-file-${this.file.tempFile ? 'additions' : 'modified'} append-right-8`;
+ return `multi-file-${this.file.tempFile ? 'addition' : 'modified'} append-right-8`;
},
},
methods: {
diff --git a/app/assets/javascripts/ide/components/repo_file.vue b/app/assets/javascripts/ide/components/repo_file.vue
index 4f102cfc026..14946f8c9fa 100644
--- a/app/assets/javascripts/ide/components/repo_file.vue
+++ b/app/assets/javascripts/ide/components/repo_file.vue
@@ -1,22 +1,29 @@
<script>
-import { mapActions } from 'vuex';
-import skeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
-import fileIcon from '~/vue_shared/components/file_icon.vue';
+import { mapActions, mapGetters } from 'vuex';
+import { n__, __, sprintf } from '~/locale';
+import tooltip from '~/vue_shared/directives/tooltip';
+import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
+import Icon from '~/vue_shared/components/icon.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 mrFileIcon from './mr_file_icon.vue';
+import NewDropdown from './new_dropdown/index.vue';
+import FileStatusIcon from './repo_file_status_icon.vue';
+import ChangedFileIcon from './changed_file_icon.vue';
+import MrFileIcon from './mr_file_icon.vue';
export default {
name: 'RepoFile',
+ directives: {
+ tooltip,
+ },
components: {
- skeletonLoadingContainer,
- newDropdown,
- fileStatusIcon,
- fileIcon,
- changedFileIcon,
- mrFileIcon,
+ SkeletonLoadingContainer,
+ NewDropdown,
+ FileStatusIcon,
+ FileIcon,
+ ChangedFileIcon,
+ MrFileIcon,
+ Icon,
},
props: {
file: {
@@ -34,6 +41,34 @@ export default {
},
},
computed: {
+ ...mapGetters([
+ 'getChangesInFolder',
+ 'getUnstagedFilesCountForPath',
+ 'getStagedFilesCountForPath',
+ ]),
+ folderUnstagedCount() {
+ return this.getUnstagedFilesCountForPath(this.file.path);
+ },
+ folderStagedCount() {
+ return this.getStagedFilesCountForPath(this.file.path);
+ },
+ changesCount() {
+ return this.getChangesInFolder(this.file.path);
+ },
+ folderChangesTooltip() {
+ if (this.changesCount === 0) return undefined;
+
+ if (this.folderUnstagedCount > 0 && this.folderStagedCount === 0) {
+ return n__('%d unstaged change', '%d unstaged changes', this.folderUnstagedCount);
+ } else if (this.folderUnstagedCount === 0 && this.folderStagedCount > 0) {
+ return n__('%d staged change', '%d staged changes', this.folderStagedCount);
+ }
+
+ return sprintf(__('%{unstaged} unstaged and %{staged} staged changes'), {
+ unstaged: this.folderUnstagedCount,
+ staged: this.folderStagedCount,
+ });
+ },
isTree() {
return this.file.type === 'tree';
},
@@ -53,10 +88,19 @@ export default {
'is-open': this.file.opened,
};
},
+ showTreeChangesCount() {
+ return this.isTree && this.changesCount > 0 && !this.file.opened;
+ },
+ showChangedFileIcon() {
+ return this.file.changed || this.file.tempFile || this.file.staged;
+ },
},
updated() {
if (this.file.type === 'blob' && this.file.active) {
- this.$el.scrollIntoView();
+ this.$el.scrollIntoView({
+ behavior: 'smooth',
+ block: 'nearest',
+ });
}
},
methods: {
@@ -104,8 +148,23 @@ export default {
<mr-file-icon
v-if="file.mrChange"
/>
+ <span
+ v-if="showTreeChangesCount"
+ class="ide-tree-changes"
+ >
+ {{ changesCount }}
+ <icon
+ v-tooltip
+ :title="folderChangesTooltip"
+ data-container="body"
+ data-placement="right"
+ name="file-modified"
+ :size="12"
+ css-classes="prepend-left-5 multi-file-modified"
+ />
+ </span>
<changed-file-icon
- v-if="file.changed || file.tempFile || file.staged"
+ v-else-if="showChangedFileIcon"
:file="file"
:show-tooltip="true"
:show-staged-icon="true"
diff --git a/app/assets/javascripts/ide/stores/getters.js b/app/assets/javascripts/ide/stores/getters.js
index 8494f07ed84..28e08c2b679 100644
--- a/app/assets/javascripts/ide/stores/getters.js
+++ b/app/assets/javascripts/ide/stores/getters.js
@@ -1,4 +1,9 @@
+<<<<<<< HEAD
import { activityBarViews } from '../constants';
+=======
+import { __ } from '~/locale';
+import { getChangesCountForFiles, filePathMatches } from './utils';
+>>>>>>> master
export const activeFile = state => state.openFiles.find(file => file.active) || null;
@@ -52,6 +57,7 @@ export const allBlobs = state =>
}, [])
.sort((a, b) => b.lastOpenedAt - a.lastOpenedAt);
+export const getChangedFile = state => path => state.changedFiles.find(f => f.path === path);
export const getStagedFile = state => path => state.stagedFiles.find(f => f.path === path);
export const lastOpenedFile = state =>
@@ -64,5 +70,20 @@ export const isReviewModeActive = state => state.currentActivityView === activit
export const someUncommitedChanges = state =>
!!(state.changedFiles.length || state.stagedFiles.length);
+export const getChangesInFolder = state => path => {
+ const changedFilesCount = state.changedFiles.filter(f => filePathMatches(f, path)).length;
+ const stagedFilesCount = state.stagedFiles.filter(
+ f => filePathMatches(f, path) && !getChangedFile(state)(f.path),
+ ).length;
+
+ return changedFilesCount + stagedFilesCount;
+};
+
+export const getUnstagedFilesCountForPath = state => path =>
+ getChangesCountForFiles(state.changedFiles, path);
+
+export const getStagedFilesCountForPath = state => path =>
+ getChangesCountForFiles(state.stagedFiles, path);
+
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
diff --git a/app/assets/javascripts/ide/stores/utils.js b/app/assets/javascripts/ide/stores/utils.js
index 59185f8f0ad..bc79ff4a542 100644
--- a/app/assets/javascripts/ide/stores/utils.js
+++ b/app/assets/javascripts/ide/stores/utils.js
@@ -33,7 +33,6 @@ export const dataStructure = () => ({
raw: '',
content: '',
parentTreeUrl: '',
- parentPath: '',
renderError: false,
base64: false,
editorRow: 1,
@@ -43,6 +42,7 @@ export const dataStructure = () => ({
viewMode: 'edit',
previewMode: null,
size: 0,
+ parentPath: null,
lastOpenedAt: 0,
});
@@ -83,7 +83,6 @@ export const decorateData = entity => {
opened,
active,
parentTreeUrl,
- parentPath,
changed,
renderError,
content,
@@ -91,6 +90,7 @@ export const decorateData = entity => {
previewMode,
file_lock,
html,
+ parentPath,
};
};
@@ -137,3 +137,9 @@ export const sortTree = sortedTree =>
}),
)
.sort(sortTreesByTypeAndName);
+
+export const filePathMatches = (f, path) =>
+ f.path.replace(new RegExp(`${f.name}$`), '').indexOf(`${path}/`) === 0;
+
+export const getChangesCountForFiles = (files, path) =>
+ files.filter(f => filePathMatches(f, path)).length;
diff --git a/app/assets/javascripts/sidebar/components/participants/participants.vue b/app/assets/javascripts/sidebar/components/participants/participants.vue
index 6d95153af28..8f9e6761d20 100644
--- a/app/assets/javascripts/sidebar/components/participants/participants.vue
+++ b/app/assets/javascripts/sidebar/components/participants/participants.vue
@@ -70,6 +70,9 @@
toggleMoreParticipants() {
this.isShowingMoreParticipants = !this.isShowingMoreParticipants;
},
+ onClickCollapsedIcon() {
+ this.$emit('toggleSidebar');
+ },
},
};
</script>
@@ -82,6 +85,7 @@
data-container="body"
data-placement="left"
:title="participantLabel"
+ @click="onClickCollapsedIcon"
>
<i
class="fa fa-users"
diff --git a/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions.vue b/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions.vue
index 3e8cc7a6630..385717e7c1e 100644
--- a/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions.vue
+++ b/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions.vue
@@ -1,6 +1,5 @@
<script>
import Store from '../../stores/sidebar_store';
-import eventHub from '../../event_hub';
import Flash from '../../../flash';
import { __ } from '../../../locale';
import subscriptions from './subscriptions.vue';
@@ -20,12 +19,6 @@ export default {
store: new Store(),
};
},
- created() {
- eventHub.$on('toggleSubscription', this.onToggleSubscription);
- },
- beforeDestroy() {
- eventHub.$off('toggleSubscription', this.onToggleSubscription);
- },
methods: {
onToggleSubscription() {
this.mediator.toggleSubscription()
@@ -42,6 +35,7 @@ export default {
<subscriptions
:loading="store.isFetching.subscriptions"
:subscribed="store.subscribed"
+ @toggleSubscription="onToggleSubscription"
/>
</div>
</template>
diff --git a/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue
index d69d100a26c..f0df759ef7a 100644
--- a/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue
+++ b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue
@@ -47,8 +47,25 @@
},
},
methods: {
+ /**
+ * We need to emit this event on both component & eventHub
+ * for 2 dependencies;
+ *
+ * 1. eventHub: This component is used in Issue Boards sidebar
+ * where component template is part of HAML
+ * and event listeners are tied to app's eventHub.
+ * 2. Component: This compone is also used in Epics in EE
+ * where listeners are tied to component event.
+ */
toggleSubscription() {
+ // App's eventHub event emission.
eventHub.$emit('toggleSubscription', this.id);
+
+ // Component event emission.
+ this.$emit('toggleSubscription', this.id);
+ },
+ onClickCollapsedIcon() {
+ this.$emit('toggleSidebar');
},
},
};
@@ -56,7 +73,10 @@
<template>
<div>
- <div class="sidebar-collapsed-icon">
+ <div
+ class="sidebar-collapsed-icon"
+ @click="onClickCollapsedIcon"
+ >
<span
v-tooltip
:title="notificationTooltip"
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.js b/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.js
deleted file mode 100644
index bf987562647..00000000000
--- a/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.js
+++ /dev/null
@@ -1,15 +0,0 @@
-export default {
- name: 'time-tracking-spent-only-pane',
- props: {
- timeSpentHumanReadable: {
- type: String,
- required: true,
- },
- },
- template: `
- <div class="time-tracking-spend-only-pane">
- <span class="bold">Spent:</span>
- {{ timeSpentHumanReadable }}
- </div>
- `,
-};
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue b/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue
new file mode 100644
index 00000000000..59cd99f8f14
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue
@@ -0,0 +1,18 @@
+<script>
+export default {
+ name: 'TimeTrackingSpentOnlyPane',
+ props: {
+ timeSpentHumanReadable: {
+ type: String,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="time-tracking-spend-only-pane">
+ <span class="bold">Spent:</span>
+ {{ timeSpentHumanReadable }}
+ </div>
+</template>
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
index 9c003aa9f8a..8f5d0bee107 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
@@ -1,7 +1,7 @@
<script>
import TimeTrackingHelpState from './help_state.vue';
import TimeTrackingCollapsedState from './collapsed_state.vue';
-import timeTrackingSpentOnlyPane from './spent_only_pane';
+import TimeTrackingSpentOnlyPane from './spent_only_pane.vue';
import TimeTrackingNoTrackingPane from './no_tracking_pane.vue';
import TimeTrackingEstimateOnlyPane from './estimate_only_pane.vue';
import TimeTrackingComparisonPane from './comparison_pane.vue';
@@ -13,7 +13,7 @@ export default {
components: {
TimeTrackingCollapsedState,
TimeTrackingEstimateOnlyPane,
- 'time-tracking-spent-only-pane': timeTrackingSpentOnlyPane,
+ TimeTrackingSpentOnlyPane,
TimeTrackingNoTrackingPane,
TimeTrackingComparisonPane,
TimeTrackingHelpState,
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index 318d3ddaece..681242f8d85 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -317,6 +317,7 @@
a {
color: $gl-text-color;
word-wrap: break-word;
+ word-break: break-word;
margin-right: 2px;
}
}
@@ -462,6 +463,7 @@
.issuable-header-text {
padding-right: 35px;
+ word-break: break-word;
> strong {
font-weight: $gl-font-weight-bold;
diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss
index e03c38e2775..4170baebffe 100644
--- a/app/assets/stylesheets/pages/repo.scss
+++ b/app/assets/stylesheets/pages/repo.scss
@@ -539,14 +539,14 @@
}
}
-.multi-file-additions,
-.multi-file-additions-solid {
- fill: $green-500;
+.multi-file-addition,
+.multi-file-addition-solid {
+ color: $green-500;
}
.multi-file-modified,
.multi-file-modified-solid {
- fill: $orange-500;
+ color: $orange-500;
}
.multi-file-commit-list-collapsed {
@@ -1026,6 +1026,12 @@
color: $gl-text-color-secondary;
}
+.ide-tree-changes {
+ display: flex;
+ align-items: center;
+ font-size: 12px;
+}
+
.ide-new-modal-label {
line-height: 34px;
}