summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-05-04 12:09:46 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-05-04 12:09:46 +0000
commit72797f4a602d0061636df39df89e11896de2a524 (patch)
treefbd4397be74910e44aaafda4093ea1e6f499d445 /app
parent5b4eca2afd809fbfba3bdcacabe547025ebe7f43 (diff)
downloadgitlab-ce-72797f4a602d0061636df39df89e11896de2a524.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/actioncable_consumer.js3
-rw-r--r--app/assets/javascripts/ide/lib/themes/index.js10
-rw-r--r--app/assets/javascripts/ide/lib/themes/monokai.js169
-rw-r--r--app/assets/javascripts/ide/lib/themes/solarized_dark.js1110
-rw-r--r--app/assets/javascripts/issuable_sidebar/queries/issue_sidebar.query.graphql15
-rw-r--r--app/assets/javascripts/lib/utils/keycodes.js3
-rw-r--r--app/assets/javascripts/lib/utils/keys.js4
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue13
-rw-r--r--app/assets/javascripts/notes/components/discussion_counter.vue19
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/assignees_realtime.vue71
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue24
-rw-r--r--app/assets/javascripts/sidebar/mount_sidebar.js18
-rw-r--r--app/assets/javascripts/sidebar/stores/sidebar_store.js4
-rw-r--r--app/assets/stylesheets/page_bundles/themes/_dark.scss92
-rw-r--r--app/assets/stylesheets/pages/notes.scss3
-rw-r--r--app/controllers/projects/issues_controller.rb4
-rw-r--r--app/graphql/types/user_type.rb2
-rw-r--r--app/policies/design_management/design_at_version_policy.rb8
-rw-r--r--app/policies/design_management/design_collection_policy.rb7
-rw-r--r--app/policies/design_management/design_policy.rb8
-rw-r--r--app/policies/design_management/version_policy.rb8
-rw-r--r--app/policies/issue_policy.rb16
-rw-r--r--app/policies/project_policy.rb19
-rw-r--r--app/views/layouts/_head.html.haml1
-rw-r--r--app/views/projects/cycle_analytics/show.html.haml3
-rw-r--r--app/views/shared/issuable/_sidebar_assignees.html.haml2
26 files changed, 1610 insertions, 26 deletions
diff --git a/app/assets/javascripts/actioncable_consumer.js b/app/assets/javascripts/actioncable_consumer.js
new file mode 100644
index 00000000000..5658ffc1a38
--- /dev/null
+++ b/app/assets/javascripts/actioncable_consumer.js
@@ -0,0 +1,3 @@
+import { createConsumer } from '@rails/actioncable';
+
+export default createConsumer();
diff --git a/app/assets/javascripts/ide/lib/themes/index.js b/app/assets/javascripts/ide/lib/themes/index.js
index 6ed9f6679a4..47d1bddc4b2 100644
--- a/app/assets/javascripts/ide/lib/themes/index.js
+++ b/app/assets/javascripts/ide/lib/themes/index.js
@@ -1,5 +1,7 @@
import white from './white';
import dark from './dark';
+import monokai from './monokai';
+import solarizedDark from './solarized_dark';
export const themes = [
{
@@ -10,6 +12,14 @@ export const themes = [
name: 'dark',
data: dark,
},
+ {
+ name: 'solarized-dark',
+ data: solarizedDark,
+ },
+ {
+ name: 'monokai',
+ data: monokai,
+ },
];
export const DEFAULT_THEME = 'white';
diff --git a/app/assets/javascripts/ide/lib/themes/monokai.js b/app/assets/javascripts/ide/lib/themes/monokai.js
new file mode 100644
index 00000000000..d7636574754
--- /dev/null
+++ b/app/assets/javascripts/ide/lib/themes/monokai.js
@@ -0,0 +1,169 @@
+/*
+
+https://github.com/brijeshb42/monaco-themes/blob/master/themes/Tomorrow-Night.json
+
+The MIT License (MIT)
+
+Copyright (c) Brijesh Bittu
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+export default {
+ base: 'vs-dark',
+ inherit: true,
+ rules: [
+ {
+ foreground: '75715e',
+ token: 'comment',
+ },
+ {
+ foreground: 'e6db74',
+ token: 'string',
+ },
+ {
+ foreground: 'ae81ff',
+ token: 'constant.numeric',
+ },
+ {
+ foreground: 'ae81ff',
+ token: 'constant.language',
+ },
+ {
+ foreground: 'ae81ff',
+ token: 'constant.character',
+ },
+ {
+ foreground: 'ae81ff',
+ token: 'constant.other',
+ },
+ {
+ foreground: 'f92672',
+ token: 'keyword',
+ },
+ {
+ foreground: 'f92672',
+ token: 'storage',
+ },
+ {
+ foreground: '66d9ef',
+ fontStyle: 'italic',
+ token: 'storage.type',
+ },
+ {
+ foreground: 'a6e22e',
+ fontStyle: 'underline',
+ token: 'entity.name.class',
+ },
+ {
+ foreground: 'a6e22e',
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ fontStyle: 'italic underline',
+ token: 'entity.other.inherited-class',
+ },
+ {
+ foreground: 'a6e22e',
+ token: 'entity.name.function',
+ },
+ {
+ foreground: 'fd971f',
+ fontStyle: 'italic',
+ token: 'variable.parameter',
+ },
+ {
+ foreground: 'f92672',
+ token: 'entity.name.tag',
+ },
+ {
+ foreground: 'a6e22e',
+ token: 'entity.other.attribute-name',
+ },
+ {
+ foreground: '66d9ef',
+ token: 'support.function',
+ },
+ {
+ foreground: '66d9ef',
+ token: 'support.constant',
+ },
+ {
+ foreground: '66d9ef',
+ fontStyle: 'italic',
+ token: 'support.type',
+ },
+ {
+ foreground: '66d9ef',
+ fontStyle: 'italic',
+ token: 'support.class',
+ },
+ {
+ foreground: 'f8f8f0',
+ background: 'f92672',
+ token: 'invalid',
+ },
+ {
+ foreground: 'f8f8f0',
+ background: 'ae81ff',
+ token: 'invalid.deprecated',
+ },
+ {
+ foreground: 'cfcfc2',
+ token: 'meta.structure.dictionary.json string.quoted.double.json',
+ },
+ {
+ foreground: '75715e',
+ token: 'meta.diff',
+ },
+ {
+ foreground: '75715e',
+ token: 'meta.diff.header',
+ },
+ {
+ foreground: 'f92672',
+ token: 'markup.deleted',
+ },
+ {
+ foreground: 'a6e22e',
+ token: 'markup.inserted',
+ },
+ {
+ foreground: 'e6db74',
+ token: 'markup.changed',
+ },
+ {
+ foreground: 'ae81ffa0',
+ token: 'constant.numeric.line-number.find-in-files - match',
+ },
+ {
+ foreground: 'e6db74',
+ token: 'entity.name.filename.find-in-files',
+ },
+ ],
+ colors: {
+ 'editor.foreground': '#F8F8F2',
+ 'editor.background': '#272822',
+ 'editor.selectionBackground': '#49483E',
+ 'editor.lineHighlightBackground': '#3E3D32',
+ 'editorCursor.foreground': '#F8F8F0',
+ 'editorWhitespace.foreground': '#3B3A32',
+ 'editorIndentGuide.activeBackground': '#9D550FB0',
+ 'editor.selectionHighlightBorder': '#222218',
+ },
+};
diff --git a/app/assets/javascripts/ide/lib/themes/solarized_dark.js b/app/assets/javascripts/ide/lib/themes/solarized_dark.js
new file mode 100644
index 00000000000..3c9414b9dc9
--- /dev/null
+++ b/app/assets/javascripts/ide/lib/themes/solarized_dark.js
@@ -0,0 +1,1110 @@
+/*
+
+https://github.com/brijeshb42/monaco-themes/blob/master/themes/Solarized-dark.json
+
+The MIT License (MIT)
+
+Copyright (c) Brijesh Bittu
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+export default {
+ base: 'vs-dark',
+ inherit: true,
+ rules: [
+ {
+ foreground: '586e75',
+ token: 'comment',
+ },
+ {
+ foreground: '2aa198',
+ token: 'string',
+ },
+ {
+ foreground: '586e75',
+ token: 'string',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'string.regexp',
+ },
+ {
+ foreground: 'd33682',
+ token: 'constant.numeric',
+ },
+ {
+ foreground: '268bd2',
+ token: 'variable.language',
+ },
+ {
+ foreground: '268bd2',
+ token: 'variable.other',
+ },
+ {
+ foreground: '859900',
+ token: 'keyword',
+ },
+ {
+ foreground: '859900',
+ token: 'storage',
+ },
+ {
+ foreground: '268bd2',
+ token: 'entity.name.class',
+ },
+ {
+ foreground: '268bd2',
+ token: 'entity.name.type.class',
+ },
+ {
+ foreground: '268bd2',
+ token: 'entity.name.function',
+ },
+ {
+ foreground: '859900',
+ token: 'punctuation.definition.variable',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.section.embedded.begin',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.section.embedded.end',
+ },
+ {
+ foreground: 'b58900',
+ token: 'constant.language',
+ },
+ {
+ foreground: 'b58900',
+ token: 'meta.preprocessor',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'support.function.construct',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'keyword.other.new',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'constant.character',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'constant.other',
+ },
+ {
+ foreground: '268bd2',
+ fontStyle: 'bold',
+ token: 'entity.name.tag',
+ },
+ {
+ foreground: '586e75',
+ token: 'punctuation.definition.tag.html',
+ },
+ {
+ foreground: '586e75',
+ token: 'punctuation.definition.tag.begin',
+ },
+ {
+ foreground: '586e75',
+ token: 'punctuation.definition.tag.end',
+ },
+ {
+ foreground: '93a1a1',
+ token: 'entity.other.attribute-name',
+ },
+ {
+ foreground: '268bd2',
+ token: 'support.function',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.separator.continuation',
+ },
+ {
+ foreground: '859900',
+ token: 'support.type',
+ },
+ {
+ foreground: '859900',
+ token: 'support.class',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'support.type.exception',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'keyword.other.special-method',
+ },
+ {
+ foreground: '2aa198',
+ token: 'string.quoted.double',
+ },
+ {
+ foreground: '2aa198',
+ token: 'string.quoted.single',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.string.begin',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.string.end',
+ },
+ {
+ foreground: 'b58900',
+ token: 'entity.name.tag.css',
+ },
+ {
+ foreground: 'b58900',
+ token: 'support.type.property-name.css',
+ },
+ {
+ foreground: 'b58900',
+ token: 'meta.property-name.css',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'source.css',
+ },
+ {
+ foreground: '586e75',
+ token: 'meta.selector.css',
+ },
+ {
+ foreground: '6c71c4',
+ token: 'punctuation.section.property-list.css',
+ },
+ {
+ foreground: '2aa198',
+ token: 'meta.property-value.css constant.numeric.css',
+ },
+ {
+ foreground: '2aa198',
+ token: 'keyword.other.unit.css',
+ },
+ {
+ foreground: '2aa198',
+ token: 'constant.other.color.rgb-value.css',
+ },
+ {
+ foreground: '2aa198',
+ token: 'meta.property-value.css',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'keyword.other.important.css',
+ },
+ {
+ foreground: '2aa198',
+ token: 'support.constant.color',
+ },
+ {
+ foreground: '859900',
+ token: 'entity.name.tag.css',
+ },
+ {
+ foreground: '586e75',
+ token: 'punctuation.separator.key-value.css',
+ },
+ {
+ foreground: '586e75',
+ token: 'punctuation.terminator.rule.css',
+ },
+ {
+ foreground: '268bd2',
+ token: 'entity.other.attribute-name.class.css',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'entity.other.attribute-name.pseudo-element.css',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'entity.other.attribute-name.pseudo-class.css',
+ },
+ {
+ foreground: '268bd2',
+ token: 'entity.other.attribute-name.id.css',
+ },
+ {
+ foreground: 'b58900',
+ token: 'meta.function.js',
+ },
+ {
+ foreground: 'b58900',
+ token: 'entity.name.function.js',
+ },
+ {
+ foreground: 'b58900',
+ token: 'support.function.dom.js',
+ },
+ {
+ foreground: 'b58900',
+ token: 'text.html.basic source.js.embedded.html',
+ },
+ {
+ foreground: '268bd2',
+ token: 'storage.type.function.js',
+ },
+ {
+ foreground: '2aa198',
+ token: 'constant.numeric.js',
+ },
+ {
+ foreground: '268bd2',
+ token: 'meta.brace.square.js',
+ },
+ {
+ foreground: '268bd2',
+ token: 'storage.type.js',
+ },
+ {
+ foreground: '93a1a1',
+ token: 'meta.brace.round',
+ },
+ {
+ foreground: '93a1a1',
+ token: 'punctuation.definition.parameters.begin.js',
+ },
+ {
+ foreground: '93a1a1',
+ token: 'punctuation.definition.parameters.end.js',
+ },
+ {
+ foreground: '268bd2',
+ token: 'meta.brace.curly.js',
+ },
+ {
+ foreground: '93a1a1',
+ fontStyle: 'italic',
+ token: 'entity.name.tag.doctype.html',
+ },
+ {
+ foreground: '93a1a1',
+ fontStyle: 'italic',
+ token: 'meta.tag.sgml.html',
+ },
+ {
+ foreground: '93a1a1',
+ fontStyle: 'italic',
+ token: 'string.quoted.double.doctype.identifiers-and-DTDs.html',
+ },
+ {
+ foreground: '839496',
+ fontStyle: 'italic',
+ token: 'comment.block.html',
+ },
+ {
+ fontStyle: 'italic',
+ token: 'entity.name.tag.script.html',
+ },
+ {
+ foreground: '2aa198',
+ token: 'source.css.embedded.html string.quoted.double.html',
+ },
+ {
+ foreground: 'cb4b16',
+ fontStyle: 'bold',
+ token: 'text.html.ruby',
+ },
+ {
+ foreground: '657b83',
+ token: 'text.html.basic meta.tag.other.html',
+ },
+ {
+ foreground: '657b83',
+ token: 'text.html.basic meta.tag.any.html',
+ },
+ {
+ foreground: '657b83',
+ token: 'text.html.basic meta.tag.block.any',
+ },
+ {
+ foreground: '657b83',
+ token: 'text.html.basic meta.tag.inline.any',
+ },
+ {
+ foreground: '657b83',
+ token: 'text.html.basic meta.tag.structure.any.html',
+ },
+ {
+ foreground: '657b83',
+ token: 'text.html.basic source.js.embedded.html',
+ },
+ {
+ foreground: '657b83',
+ token: 'punctuation.separator.key-value.html',
+ },
+ {
+ foreground: '657b83',
+ token: 'text.html.basic entity.other.attribute-name.html',
+ },
+ {
+ foreground: '2aa198',
+ token: 'text.html.basic meta.tag.structure.any.html punctuation.definition.string.begin.html',
+ },
+ {
+ foreground: '2aa198',
+ token: 'punctuation.definition.string.begin.html',
+ },
+ {
+ foreground: '2aa198',
+ token: 'punctuation.definition.string.end.html',
+ },
+ {
+ foreground: '268bd2',
+ fontStyle: 'bold',
+ token: 'entity.name.tag.block.any.html',
+ },
+ {
+ fontStyle: 'italic',
+ token: 'source.css.embedded.html entity.name.tag.style.html',
+ },
+ {
+ foreground: '839496',
+ fontStyle: 'italic',
+ token: 'source.css.embedded.html',
+ },
+ {
+ foreground: '839496',
+ fontStyle: 'italic',
+ token: 'comment.block.html',
+ },
+ {
+ foreground: '268bd2',
+ token: 'punctuation.definition.variable.ruby',
+ },
+ {
+ foreground: '657b83',
+ token: 'meta.function.method.with-arguments.ruby',
+ },
+ {
+ foreground: '2aa198',
+ token: 'variable.language.ruby',
+ },
+ {
+ foreground: '268bd2',
+ token: 'entity.name.function.ruby',
+ },
+ {
+ foreground: '859900',
+ fontStyle: 'bold',
+ token: 'keyword.control.ruby',
+ },
+ {
+ foreground: '859900',
+ fontStyle: 'bold',
+ token: 'keyword.control.def.ruby',
+ },
+ {
+ foreground: '859900',
+ token: 'keyword.control.class.ruby',
+ },
+ {
+ foreground: '859900',
+ token: 'meta.class.ruby',
+ },
+ {
+ foreground: 'b58900',
+ token: 'entity.name.type.class.ruby',
+ },
+ {
+ foreground: '859900',
+ token: 'keyword.control.ruby',
+ },
+ {
+ foreground: 'b58900',
+ token: 'support.class.ruby',
+ },
+ {
+ foreground: '859900',
+ token: 'keyword.other.special-method.ruby',
+ },
+ {
+ foreground: '2aa198',
+ token: 'constant.language.ruby',
+ },
+ {
+ foreground: '2aa198',
+ token: 'constant.numeric.ruby',
+ },
+ {
+ foreground: 'b58900',
+ token: 'variable.other.constant.ruby',
+ },
+ {
+ foreground: '2aa198',
+ token: 'constant.other.symbol.ruby',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.section.embedded.ruby',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.string.begin.ruby',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.string.end.ruby',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'keyword.other.special-method.ruby',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'keyword.control.import.include.php',
+ },
+ {
+ foreground: '839496',
+ token: 'text.html.ruby meta.tag.inline.any.html',
+ },
+ {
+ foreground: '2aa198',
+ token: 'text.html.ruby punctuation.definition.string.begin',
+ },
+ {
+ foreground: '2aa198',
+ token: 'text.html.ruby punctuation.definition.string.end',
+ },
+ {
+ foreground: '839496',
+ token: 'punctuation.definition.string.begin',
+ },
+ {
+ foreground: '839496',
+ token: 'punctuation.definition.string.end',
+ },
+ {
+ foreground: '839496',
+ token: 'support.class.php',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'keyword.operator.index-start.php',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'keyword.operator.index-end.php',
+ },
+ {
+ foreground: '586e75',
+ token: 'meta.array.php',
+ },
+ {
+ foreground: 'b58900',
+ token: 'meta.array.php support.function.construct.php',
+ },
+ {
+ foreground: 'b58900',
+ token: 'meta.array.empty.php support.function.construct.php',
+ },
+ {
+ foreground: 'b58900',
+ token: 'support.function.construct.php',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.array.begin',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.array.end',
+ },
+ {
+ foreground: '2aa198',
+ token: 'constant.numeric.php',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'keyword.other.new.php',
+ },
+ {
+ foreground: '839496',
+ token: 'keyword.operator.class',
+ },
+ {
+ foreground: '93a1a1',
+ token: 'variable.other.property.php',
+ },
+ {
+ foreground: 'b58900',
+ token: 'storage.modifier.extends.php',
+ },
+ {
+ foreground: 'b58900',
+ token: 'storage.type.class.php',
+ },
+ {
+ foreground: 'b58900',
+ token: 'keyword.operator.class.php',
+ },
+ {
+ foreground: '839496',
+ token: 'punctuation.terminator.expression.php',
+ },
+ {
+ foreground: '586e75',
+ token: 'meta.other.inherited-class.php',
+ },
+ {
+ foreground: '859900',
+ token: 'storage.type.php',
+ },
+ {
+ foreground: '93a1a1',
+ token: 'entity.name.function.php',
+ },
+ {
+ foreground: '859900',
+ token: 'support.function.construct.php',
+ },
+ {
+ foreground: '839496',
+ token: 'entity.name.type.class.php',
+ },
+ {
+ foreground: '839496',
+ token: 'meta.function-call.php',
+ },
+ {
+ foreground: '839496',
+ token: 'meta.function-call.static.php',
+ },
+ {
+ foreground: '839496',
+ token: 'meta.function-call.object.php',
+ },
+ {
+ foreground: '93a1a1',
+ token: 'keyword.other.phpdoc',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'source.php.embedded.block.html',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'storage.type.function.php',
+ },
+ {
+ foreground: '2aa198',
+ token: 'constant.numeric.c',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'meta.preprocessor.c.include',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'meta.preprocessor.macro.c',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'keyword.control.import.define.c',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'keyword.control.import.include.c',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'entity.name.function.preprocessor.c',
+ },
+ {
+ foreground: '2aa198',
+ token: 'meta.preprocessor.c.include string.quoted.other.lt-gt.include.c',
+ },
+ {
+ foreground: '2aa198',
+ token: 'meta.preprocessor.c.include punctuation.definition.string.begin.c',
+ },
+ {
+ foreground: '2aa198',
+ token: 'meta.preprocessor.c.include punctuation.definition.string.end.c',
+ },
+ {
+ foreground: '586e75',
+ token: 'support.function.C99.c',
+ },
+ {
+ foreground: '586e75',
+ token: 'support.function.any-method.c',
+ },
+ {
+ foreground: '586e75',
+ token: 'entity.name.function.c',
+ },
+ {
+ foreground: '2aa198',
+ token: 'punctuation.definition.string.begin.c',
+ },
+ {
+ foreground: '2aa198',
+ token: 'punctuation.definition.string.end.c',
+ },
+ {
+ foreground: 'b58900',
+ token: 'storage.type.c',
+ },
+ {
+ foreground: 'e0eddd',
+ background: 'b58900',
+ fontStyle: 'italic',
+ token: 'meta.diff',
+ },
+ {
+ foreground: 'e0eddd',
+ background: 'b58900',
+ fontStyle: 'italic',
+ token: 'meta.diff.header',
+ },
+ {
+ foreground: 'dc322f',
+ background: 'eee8d5',
+ token: 'markup.deleted',
+ },
+ {
+ foreground: 'cb4b16',
+ background: 'eee8d5',
+ token: 'markup.changed',
+ },
+ {
+ foreground: '219186',
+ background: 'eee8d5',
+ token: 'markup.inserted',
+ },
+ {
+ foreground: 'e0eddd',
+ background: 'b58900',
+ token: 'text.html.markdown meta.dummy.line-break',
+ },
+ {
+ foreground: '2aa198',
+ token: 'text.html.markdown markup.raw.inline',
+ },
+ {
+ foreground: '2aa198',
+ token: 'text.restructuredtext markup.raw',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'other.package.exclude',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'other.remove',
+ },
+ {
+ foreground: '2aa198',
+ token: 'other.add',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.section.group.tex',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.arguments.begin.latex',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.arguments.end.latex',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.arguments.latex',
+ },
+ {
+ foreground: 'b58900',
+ token: 'meta.group.braces.tex',
+ },
+ {
+ foreground: 'b58900',
+ token: 'string.other.math.tex',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'variable.parameter.function.latex',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.constant.math.tex',
+ },
+ {
+ foreground: '2aa198',
+ token: 'text.tex.latex constant.other.math.tex',
+ },
+ {
+ foreground: '2aa198',
+ token: 'constant.other.general.math.tex',
+ },
+ {
+ foreground: '2aa198',
+ token: 'constant.other.general.math.tex',
+ },
+ {
+ foreground: '2aa198',
+ token: 'constant.character.math.tex',
+ },
+ {
+ foreground: 'b58900',
+ token: 'string.other.math.tex',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.string.begin.tex',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.string.end.tex',
+ },
+ {
+ foreground: '2aa198',
+ token: 'keyword.control.label.latex',
+ },
+ {
+ foreground: '2aa198',
+ token: 'text.tex.latex constant.other.general.math.tex',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'variable.parameter.definition.label.latex',
+ },
+ {
+ foreground: '859900',
+ token: 'support.function.be.latex',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'support.function.section.latex',
+ },
+ {
+ foreground: '2aa198',
+ token: 'support.function.general.tex',
+ },
+ {
+ fontStyle: 'italic',
+ token: 'punctuation.definition.comment.tex',
+ },
+ {
+ fontStyle: 'italic',
+ token: 'comment.line.percentage.tex',
+ },
+ {
+ foreground: '2aa198',
+ token: 'keyword.control.ref.latex',
+ },
+ {
+ foreground: '586e75',
+ token: 'string.quoted.double.block.python',
+ },
+ {
+ foreground: '859900',
+ token: 'storage.type.class.python',
+ },
+ {
+ foreground: '859900',
+ token: 'storage.type.function.python',
+ },
+ {
+ foreground: '859900',
+ token: 'storage.modifier.global.python',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'keyword.control.import.python',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'keyword.control.import.from.python',
+ },
+ {
+ foreground: 'b58900',
+ token: 'support.type.exception.python',
+ },
+ {
+ foreground: '859900',
+ token: 'support.function.builtin.shell',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'variable.other.normal.shell',
+ },
+ {
+ foreground: '268bd2',
+ token: 'source.shell',
+ },
+ {
+ foreground: '586e75',
+ token: 'meta.scope.for-in-loop.shell',
+ },
+ {
+ foreground: '586e75',
+ token: 'variable.other.loop.shell',
+ },
+ {
+ foreground: '859900',
+ token: 'punctuation.definition.string.end.shell',
+ },
+ {
+ foreground: '859900',
+ token: 'punctuation.definition.string.begin.shell',
+ },
+ {
+ foreground: '586e75',
+ token: 'meta.scope.case-block.shell',
+ },
+ {
+ foreground: '586e75',
+ token: 'meta.scope.case-body.shell',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.logical-expression.shell',
+ },
+ {
+ fontStyle: 'italic',
+ token: 'comment.line.number-sign.shell',
+ },
+ {
+ foreground: 'cb4b16',
+ token: 'keyword.other.import.java',
+ },
+ {
+ foreground: '586e75',
+ token: 'storage.modifier.import.java',
+ },
+ {
+ foreground: 'b58900',
+ token: 'meta.class.java storage.modifier.java',
+ },
+ {
+ foreground: '586e75',
+ token: 'source.java comment.block',
+ },
+ {
+ foreground: '586e75',
+ token:
+ 'comment.block meta.documentation.tag.param.javadoc keyword.other.documentation.param.javadoc',
+ },
+ {
+ foreground: 'b58900',
+ token: 'punctuation.definition.variable.perl',
+ },
+ {
+ foreground: 'b58900',
+ token: 'variable.other.readwrite.global.perl',
+ },
+ {
+ foreground: 'b58900',
+ token: 'variable.other.predefined.perl',
+ },
+ {
+ foreground: 'b58900',
+ token: 'keyword.operator.comparison.perl',
+ },
+ {
+ foreground: '859900',
+ token: 'support.function.perl',
+ },
+ {
+ foreground: '586e75',
+ fontStyle: 'italic',
+ token: 'comment.line.number-sign.perl',
+ },
+ {
+ foreground: '2aa198',
+ token: 'punctuation.definition.string.begin.perl',
+ },
+ {
+ foreground: '2aa198',
+ token: 'punctuation.definition.string.end.perl',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'constant.character.escape.perl',
+ },
+ {
+ foreground: '268bd2',
+ token: 'markup.heading.markdown',
+ },
+ {
+ foreground: '268bd2',
+ token: 'markup.heading.1.markdown',
+ },
+ {
+ foreground: '268bd2',
+ token: 'markup.heading.2.markdown',
+ },
+ {
+ foreground: '268bd2',
+ token: 'markup.heading.3.markdown',
+ },
+ {
+ foreground: '268bd2',
+ token: 'markup.heading.4.markdown',
+ },
+ {
+ foreground: '268bd2',
+ token: 'markup.heading.5.markdown',
+ },
+ {
+ foreground: '268bd2',
+ token: 'markup.heading.6.markdown',
+ },
+ {
+ foreground: '839496',
+ fontStyle: 'bold',
+ token: 'markup.bold.markdown',
+ },
+ {
+ foreground: '839496',
+ fontStyle: 'italic',
+ token: 'markup.italic.markdown',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.bold.markdown',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.italic.markdown',
+ },
+ {
+ foreground: 'dc322f',
+ token: 'punctuation.definition.raw.markdown',
+ },
+ {
+ foreground: 'b58900',
+ token: 'markup.list.unnumbered.markdown',
+ },
+ {
+ foreground: '859900',
+ token: 'markup.list.numbered.markdown',
+ },
+ {
+ foreground: '2aa198',
+ token: 'markup.raw.block.markdown',
+ },
+ {
+ foreground: '2aa198',
+ token: 'markup.raw.inline.markdown',
+ },
+ {
+ foreground: '6c71c4',
+ token: 'markup.quote.markdown',
+ },
+ {
+ foreground: '6c71c4',
+ token: 'punctuation.definition.blockquote.markdown',
+ },
+ {
+ foreground: 'd33682',
+ token: 'meta.separator.markdown',
+ },
+ {
+ foreground: '586e75',
+ fontStyle: 'italic',
+ token: 'meta.image.inline.markdown',
+ },
+ {
+ foreground: '586e75',
+ fontStyle: 'italic',
+ token: 'markup.underline.link.markdown',
+ },
+ {
+ foreground: '93a1a1',
+ token: 'string.other.link.title.markdown',
+ },
+ {
+ foreground: '93a1a1',
+ token: 'string.other.link.description.markdown',
+ },
+ {
+ foreground: '586e75',
+ token: 'punctuation.definition.link.markdown',
+ },
+ {
+ foreground: '586e75',
+ token: 'punctuation.definition.metadata.markdown',
+ },
+ {
+ foreground: '586e75',
+ token: 'punctuation.definition.string.begin.markdown',
+ },
+ {
+ foreground: '586e75',
+ token: 'punctuation.definition.string.end.markdown',
+ },
+ {
+ foreground: '586e75',
+ token: 'punctuation.definition.constant.markdown',
+ },
+ {
+ foreground: 'eee8d5',
+ background: 'eee8d5',
+ token: 'sublimelinter.notes',
+ },
+ {
+ foreground: '93a1a1',
+ background: '93a1a1',
+ token: 'sublimelinter.outline.illegal',
+ },
+ {
+ background: 'dc322f',
+ token: 'sublimelinter.underline.illegal',
+ },
+ {
+ foreground: '839496',
+ background: '839496',
+ token: 'sublimelinter.outline.warning',
+ },
+ {
+ background: 'b58900',
+ token: 'sublimelinter.underline.warning',
+ },
+ {
+ foreground: '657b83',
+ background: '657b83',
+ token: 'sublimelinter.outline.violation',
+ },
+ {
+ background: 'cb4b16',
+ token: 'sublimelinter.underline.violation',
+ },
+ ],
+ colors: {
+ 'editor.foreground': '#839496',
+ 'editor.background': '#002B36',
+ 'editor.selectionBackground': '#073642',
+ 'editor.lineHighlightBackground': '#073642',
+ 'editorCursor.foreground': '#819090',
+ 'editorWhitespace.foreground': '#073642',
+ },
+};
diff --git a/app/assets/javascripts/issuable_sidebar/queries/issue_sidebar.query.graphql b/app/assets/javascripts/issuable_sidebar/queries/issue_sidebar.query.graphql
new file mode 100644
index 00000000000..fe01d2c2e78
--- /dev/null
+++ b/app/assets/javascripts/issuable_sidebar/queries/issue_sidebar.query.graphql
@@ -0,0 +1,15 @@
+#import "~/graphql_shared/fragments/author.fragment.graphql"
+
+query getProjectIssue($iid: String!, $fullPath: ID!) {
+ project(fullPath: $fullPath) {
+ issue(iid: $iid) {
+ assignees {
+ nodes {
+ ...Author
+ id
+ state
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/lib/utils/keycodes.js b/app/assets/javascripts/lib/utils/keycodes.js
index 16bffc5c2cf..618266f7a09 100644
--- a/app/assets/javascripts/lib/utils/keycodes.js
+++ b/app/assets/javascripts/lib/utils/keycodes.js
@@ -1,3 +1,6 @@
+// `e.keyCode` is deprecated, these values should be migrated
+// See: https://gitlab.com/gitlab-org/gitlab/-/issues/216102
+
export const BACKSPACE_KEY_CODE = 8;
export const ENTER_KEY_CODE = 13;
export const ESC_KEY_CODE = 27;
diff --git a/app/assets/javascripts/lib/utils/keys.js b/app/assets/javascripts/lib/utils/keys.js
new file mode 100644
index 00000000000..8e5420e87ea
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/keys.js
@@ -0,0 +1,4 @@
+/* eslint-disable @gitlab/require-i18n-strings */
+
+export const ESC_KEY = 'Escape';
+export const ESC_KEY_IE11 = 'Esc'; // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index 1877f58ed96..67835a5e356 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -19,6 +19,7 @@ import {
import DashboardPanel from './dashboard_panel.vue';
import { s__ } from '~/locale';
import createFlash from '~/flash';
+import { ESC_KEY, ESC_KEY_IE11 } from '~/lib/utils/keys';
import CustomMetricsFormFields from '~/custom_metrics/components/custom_metrics_form_fields.vue';
import { mergeUrlParams, redirectTo, updateHistory } from '~/lib/utils/url_utility';
import invalidUrl from '~/lib/utils/invalid_url';
@@ -248,6 +249,10 @@ export default {
logsPath: this.logsPath,
currentEnvironmentName: this.currentEnvironmentName,
});
+ window.addEventListener('keyup', this.onKeyup);
+ },
+ destroyed() {
+ window.removeEventListener('keyup', this.onKeyup);
},
mounted() {
if (!this.hasMetrics) {
@@ -371,13 +376,19 @@ export default {
onGoBack() {
this.clearExpandedPanel();
},
+ onKeyup(event) {
+ const { key } = event;
+ if (key === ESC_KEY || key === ESC_KEY_IE11) {
+ this.clearExpandedPanel();
+ }
+ },
},
addMetric: {
title: s__('Metrics|Add metric'),
modalId: 'add-metric',
},
i18n: {
- goBackLabel: s__('Metrics|Go back'),
+ goBackLabel: s__('Metrics|Go back (Esc)'),
},
};
</script>
diff --git a/app/assets/javascripts/notes/components/discussion_counter.vue b/app/assets/javascripts/notes/components/discussion_counter.vue
index 07952f9edd9..4a1a1086329 100644
--- a/app/assets/javascripts/notes/components/discussion_counter.vue
+++ b/app/assets/javascripts/notes/components/discussion_counter.vue
@@ -29,9 +29,6 @@ export default {
resolveAllDiscussionsIssuePath() {
return this.getNoteableData.create_issue_to_resolve_discussions_path;
},
- resolvedDiscussionsCount() {
- return this.resolvableDiscussionsCount - this.unresolvedDiscussionsCount;
- },
toggeableDiscussions() {
return this.discussions.filter(discussion => !discussion.individual_note);
},
@@ -60,15 +57,15 @@ export default {
<div class="full-width-mobile d-flex d-sm-flex">
<div class="line-resolve-all">
<span
- :class="{ 'is-active': allResolved }"
- class="line-resolve-btn is-disabled"
- type="button"
+ :class="{ 'line-resolve-btn is-active': allResolved, 'line-resolve-text': !allResolved }"
>
- <icon :name="allResolved ? 'check-circle-filled' : 'check-circle'" />
- </span>
- <span class="line-resolve-text">
- {{ resolvedDiscussionsCount }}/{{ resolvableDiscussionsCount }}
- {{ n__('thread resolved', 'threads resolved', resolvableDiscussionsCount) }}
+ <template v-if="allResolved">
+ <icon name="check-circle-filled" />
+ {{ __('All threads resolved') }}
+ </template>
+ <template v-else>
+ {{ n__('%d unresolved thread', '%d unresolved threads', unresolvedDiscussionsCount) }}
+ </template>
</span>
</div>
<div
diff --git a/app/assets/javascripts/sidebar/components/assignees/assignees_realtime.vue b/app/assets/javascripts/sidebar/components/assignees/assignees_realtime.vue
new file mode 100644
index 00000000000..f6646823c5c
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/assignees/assignees_realtime.vue
@@ -0,0 +1,71 @@
+<script>
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import query from '~/issuable_sidebar/queries/issue_sidebar.query.graphql';
+import actionCable from '~/actioncable_consumer';
+
+export default {
+ name: 'AssigneesRealtime',
+ props: {
+ mediator: {
+ type: Object,
+ required: true,
+ },
+ issuableIid: {
+ type: String,
+ required: true,
+ },
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ },
+ apollo: {
+ project: {
+ query,
+ variables() {
+ return {
+ iid: this.issuableIid,
+ fullPath: this.projectPath,
+ };
+ },
+ result(data) {
+ this.handleFetchResult(data);
+ },
+ },
+ },
+ mounted() {
+ this.initActionCablePolling();
+ },
+ methods: {
+ received(data) {
+ if (data.event === 'updated') {
+ this.$apollo.queries.project.refetch();
+ }
+ },
+ initActionCablePolling() {
+ actionCable.subscriptions.create(
+ {
+ channel: 'IssuesChannel',
+ project_path: this.projectPath,
+ iid: this.issuableIid,
+ },
+ { received: this.received },
+ );
+ },
+ handleFetchResult({ data }) {
+ const { nodes } = data.project.issue.assignees;
+
+ const assignees = nodes.map(n => ({
+ ...n,
+ avatar_url: n.avatarUrl,
+ id: getIdFromGraphQLId(n.id),
+ }));
+
+ this.mediator.store.setAssigneesFromRealtime(assignees);
+ },
+ },
+ render() {
+ return this.$slots.default;
+ },
+};
+</script>
diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue
index ce592720531..0906d5abec3 100644
--- a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue
@@ -3,8 +3,10 @@ import Flash from '~/flash';
import eventHub from '~/sidebar/event_hub';
import Store from '~/sidebar/stores/sidebar_store';
import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import AssigneeTitle from './assignee_title.vue';
import Assignees from './assignees.vue';
+import AssigneesRealtime from './assignees_realtime.vue';
import { __ } from '~/locale';
export default {
@@ -12,7 +14,9 @@ export default {
components: {
AssigneeTitle,
Assignees,
+ AssigneesRealtime,
},
+ mixins: [glFeatureFlagsMixin()],
props: {
mediator: {
type: Object,
@@ -32,6 +36,14 @@ export default {
required: false,
default: 'issue',
},
+ issuableIid: {
+ type: String,
+ required: true,
+ },
+ projectPath: {
+ type: String,
+ required: true,
+ },
},
data() {
return {
@@ -39,6 +51,12 @@ export default {
loading: false,
};
},
+ computed: {
+ shouldEnableRealtime() {
+ // Note: Realtime is only available on issues right now, future support for MR wil be built later.
+ return this.glFeatures.realTimeIssueSidebar && this.issuableType === 'issue';
+ },
+ },
created() {
this.removeAssignee = this.store.removeAssignee.bind(this.store);
this.addAssignee = this.store.addAssignee.bind(this.store);
@@ -84,6 +102,12 @@ export default {
<template>
<div>
+ <assignees-realtime
+ v-if="shouldEnableRealtime"
+ :issuable-iid="issuableIid"
+ :project-path="projectPath"
+ :mediator="mediator"
+ />
<assignee-title
:number-of-assignees="store.assignees.length"
:loading="loading || store.isFetching.assignees"
diff --git a/app/assets/javascripts/sidebar/mount_sidebar.js b/app/assets/javascripts/sidebar/mount_sidebar.js
index 6f8214b18ee..05d9ce240f3 100644
--- a/app/assets/javascripts/sidebar/mount_sidebar.js
+++ b/app/assets/javascripts/sidebar/mount_sidebar.js
@@ -1,5 +1,6 @@
import $ from 'jquery';
import Vue from 'vue';
+import VueApollo from 'vue-apollo';
import SidebarTimeTracking from './components/time_tracking/sidebar_time_tracking.vue';
import SidebarAssignees from './components/assignees/sidebar_assignees.vue';
import ConfidentialIssueSidebar from './components/confidential/confidential_issue_sidebar.vue';
@@ -8,17 +9,28 @@ import LockIssueSidebar from './components/lock/lock_issue_sidebar.vue';
import sidebarParticipants from './components/participants/sidebar_participants.vue';
import sidebarSubscriptions from './components/subscriptions/sidebar_subscriptions.vue';
import Translate from '../vue_shared/translate';
+import createDefaultClient from '~/lib/graphql';
Vue.use(Translate);
+Vue.use(VueApollo);
+
+function getSidebarOptions() {
+ return JSON.parse(document.querySelector('.js-sidebar-options').innerHTML);
+}
function mountAssigneesComponent(mediator) {
const el = document.getElementById('js-vue-sidebar-assignees');
+ const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+ });
if (!el) return;
+ const { iid, fullPath } = getSidebarOptions();
// eslint-disable-next-line no-new
new Vue({
el,
+ apolloProvider,
components: {
SidebarAssignees,
},
@@ -26,6 +38,8 @@ function mountAssigneesComponent(mediator) {
createElement('sidebar-assignees', {
props: {
mediator,
+ issuableIid: String(iid),
+ projectPath: fullPath,
field: el.dataset.field,
signedIn: el.hasAttribute('data-signed-in'),
issuableType: gl.utils.isInIssuePage() ? 'issue' : 'merge_request',
@@ -144,6 +158,4 @@ export function mountSidebar(mediator) {
mountTimeTrackingComponent();
}
-export function getSidebarOptions() {
- return JSON.parse(document.querySelector('.js-sidebar-options').innerHTML);
-}
+export { getSidebarOptions };
diff --git a/app/assets/javascripts/sidebar/stores/sidebar_store.js b/app/assets/javascripts/sidebar/stores/sidebar_store.js
index 66f7f9e3c66..095f93b72a9 100644
--- a/app/assets/javascripts/sidebar/stores/sidebar_store.js
+++ b/app/assets/javascripts/sidebar/stores/sidebar_store.js
@@ -89,6 +89,10 @@ export default class SidebarStore {
this.assignees = [];
}
+ setAssigneesFromRealtime(data) {
+ this.assignees = data;
+ }
+
setAutocompleteProjects(projects) {
this.autocompleteProjects = projects;
}
diff --git a/app/assets/stylesheets/page_bundles/themes/_dark.scss b/app/assets/stylesheets/page_bundles/themes/_dark.scss
index ef9a648a93e..66b4b745532 100644
--- a/app/assets/stylesheets/page_bundles/themes/_dark.scss
+++ b/app/assets/stylesheets/page_bundles/themes/_dark.scss
@@ -27,6 +27,9 @@
$btn-disabled-border: rgba(223, 223, 223, 0.24);
$btn-disabled-color: rgba(145, 145, 145, 0.48);
+ $dropdown-background: #404040;
+ $dropdown-hover-background: #525252;
+
$diff-insert: rgba(155, 185, 85, 0.2);
$diff-remove: rgba(255, 0, 0, 0.2);
@@ -54,7 +57,12 @@
textarea,
.md-area.is-focused,
.ide-entry-dropdown-toggle,
- .nav-links:not(.quick-links) li:not(.md-header-toolbar) a:hover {
+ .nav-links:not(.quick-links) li:not(.md-header-toolbar) a:hover,
+ .dropdown-menu li button,
+ .ide-merge-request-project-path,
+ .dropdown-menu-selectable li a.is-active,
+ .dropdown-menu-inner-title,
+ .dropdown-menu-inner-content {
color: $text-color;
}
@@ -82,11 +90,17 @@
color: $text-color !important;
}
+ input[type='search']::placeholder,
input[type='text']::placeholder,
- textarea::placeholder {
+ textarea::placeholder,
+ .dropdown-input .fa {
color: $input-border;
}
+ .ide-nav-form .input-icon {
+ fill: $input-border;
+ }
+
.ide-staged-action-btn {
background-color: transparent;
}
@@ -112,7 +126,8 @@
background-color: inherit;
}
- .ide-sidebar-link:hover {
+ .ide-sidebar-link:hover,
+ .multi-file-tabs li {
background-color: $background-hover;
}
@@ -204,21 +219,40 @@
background-color: $footer-background;
}
- input[type='text'] {
+ input[type='text'],
+ input[type='search'],
+ .filtered-search-box {
border-color: $input-border;
- background: $input-background;
+ background-color: $input-background;
}
input[type='text'],
+ input[type='search'],
+ .filtered-search-box,
textarea {
color: $input-color !important;
}
+ .filtered-search-box input[type='search'] {
+ border-color: transparent;
+ }
+
+ .filtered-search-token .value-container,
+ .filtered-search-term .value-container {
+ background-color: $dropdown-hover-background;
+
+ color: $text-color;
+
+ &:hover {
+ background-color: $input-border;
+ }
+ }
+
.ide-entry-dropdown-toggle:hover {
background: $gray-800;
}
- .btn:hover {
+ .btn:not(.btn-link):hover {
border-width: 2px;
padding: 5px 9px;
}
@@ -257,6 +291,48 @@
}
}
+ .dropdown-menu {
+ color: $text-color;
+ border-color: $background;
+ background-color: $dropdown-background;
+
+ .divider,
+ .nav-links:not(.quick-links) {
+ background-color: $dropdown-hover-background;
+ border-color: $dropdown-hover-background;
+ }
+
+ .nav-links li a.active {
+ border-color: $highlight-accent;
+ }
+
+ .ide-nav-form .nav-links li a:not(.active) {
+ background-color: $dropdown-background;
+ }
+
+ .nav-links:not(.quick-links) li:not(.md-header-toolbar) a {
+ color: $text-color;
+
+ &.active {
+ color: $text-color;
+ }
+ }
+
+ li > a:not(.disable-hover):hover,
+ li > a:not(.disable-hover):focus,
+ li button:not(.disable-hover):hover,
+ li button:not(.disable-hover):focus,
+ li button.is-focused {
+ background-color: $dropdown-hover-background;
+ color: $text-color;
+ }
+ }
+
+ .dropdown-title,
+ .dropdown-input {
+ border-color: $dropdown-hover-background !important;
+ }
+
.btn-primary {
background-color: $btn-primary-background;
border-color: $btn-primary-border !important;
@@ -320,3 +396,7 @@
.navbar.theme-dark {
border-bottom-color: transparent;
}
+
+.theme-dark ~ .popover {
+ box-shadow: none;
+}
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index c60e3c6b2b1..6445695bc6b 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -908,11 +908,10 @@ $note-form-margin-left: 72px;
border-right: 0;
.line-resolve-btn {
- margin-right: 5px;
color: $gray-700;
svg {
- vertical-align: middle;
+ vertical-align: text-top;
}
}
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 95b4d5e5658..da5401ffa00 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -50,6 +50,10 @@ class Projects::IssuesController < Projects::ApplicationController
push_frontend_feature_flag(:save_issuable_health_status, project.group, default_enabled: true)
end
+ before_action only: :show do
+ push_frontend_feature_flag(:real_time_issue_sidebar, @project)
+ end
+
around_action :allow_gitaly_ref_name_caching, only: [:discussions]
respond_to :html
diff --git a/app/graphql/types/user_type.rb b/app/graphql/types/user_type.rb
index 5cee0c2cf8f..29a3f5d452f 100644
--- a/app/graphql/types/user_type.rb
+++ b/app/graphql/types/user_type.rb
@@ -14,6 +14,8 @@ module Types
description: 'ID of the user'
field :name, GraphQL::STRING_TYPE, null: false,
description: 'Human-readable name of the user'
+ field :state, GraphQL::STRING_TYPE, null: false,
+ description: 'State of the issue'
field :username, GraphQL::STRING_TYPE, null: false,
description: 'Username of the user. Unique within this instance of GitLab'
field :avatar_url, GraphQL::STRING_TYPE, null: true,
diff --git a/app/policies/design_management/design_at_version_policy.rb b/app/policies/design_management/design_at_version_policy.rb
new file mode 100644
index 00000000000..9decbc0c4b2
--- /dev/null
+++ b/app/policies/design_management/design_at_version_policy.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+module DesignManagement
+ class DesignAtVersionPolicy < ::BasePolicy
+ delegate { @subject.version }
+ delegate { @subject.design }
+ end
+end
diff --git a/app/policies/design_management/design_collection_policy.rb b/app/policies/design_management/design_collection_policy.rb
new file mode 100644
index 00000000000..6a833da27cc
--- /dev/null
+++ b/app/policies/design_management/design_collection_policy.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module DesignManagement
+ class DesignCollectionPolicy < DesignPolicy
+ # Delegates everything to the `issue` just like the `DesignPolicy`
+ end
+end
diff --git a/app/policies/design_management/design_policy.rb b/app/policies/design_management/design_policy.rb
new file mode 100644
index 00000000000..57846095f80
--- /dev/null
+++ b/app/policies/design_management/design_policy.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+module DesignManagement
+ class DesignPolicy < ::BasePolicy
+ # The IssuePolicy will delegate to the ProjectPolicy
+ delegate { @subject.issue }
+ end
+end
diff --git a/app/policies/design_management/version_policy.rb b/app/policies/design_management/version_policy.rb
new file mode 100644
index 00000000000..1c59ceaea98
--- /dev/null
+++ b/app/policies/design_management/version_policy.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+module DesignManagement
+ class VersionPolicy < ::BasePolicy
+ # The IssuePolicy will delegate to the ProjectPolicy
+ delegate { @subject.issue }
+ end
+end
diff --git a/app/policies/issue_policy.rb b/app/policies/issue_policy.rb
index 20df823c737..28baa0d8338 100644
--- a/app/policies/issue_policy.rb
+++ b/app/policies/issue_policy.rb
@@ -15,6 +15,9 @@ class IssuePolicy < IssuablePolicy
desc "Issue is confidential"
condition(:confidential, scope: :subject) { @subject.confidential? }
+ desc "Issue has moved"
+ condition(:moved) { @subject.moved? }
+
rule { confidential & ~can_read_confidential }.policy do
prevent(*create_read_update_admin_destroy(:issue))
prevent :read_issue_iid
@@ -25,6 +28,15 @@ class IssuePolicy < IssuablePolicy
rule { locked }.policy do
prevent :reopen_issue
end
-end
-IssuePolicy.prepend_if_ee('::EE::IssuePolicy')
+ rule { ~can?(:read_issue) }.policy do
+ prevent :read_design
+ prevent :create_design
+ prevent :destroy_design
+ end
+
+ rule { locked | moved }.policy do
+ prevent :create_design
+ prevent :destroy_design
+ end
+end
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 52099bbd0b8..4e0bcfe0985 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -11,6 +11,7 @@ class ProjectPolicy < BasePolicy
milestone
snippet
wiki
+ design
note
pipeline
pipeline_schedule
@@ -107,6 +108,11 @@ class ProjectPolicy < BasePolicy
)
end
+ with_scope :subject
+ condition(:design_management_disabled) do
+ !@subject.design_management_enabled?
+ end
+
# We aren't checking `:read_issue` or `:read_merge_request` in this case
# because it could be possible for a user to see an issuable-iid
# (`:read_issue_iid` or `:read_merge_request_iid`) but then wouldn't be
@@ -299,6 +305,8 @@ class ProjectPolicy < BasePolicy
enable :create_metrics_dashboard_annotation
enable :delete_metrics_dashboard_annotation
enable :update_metrics_dashboard_annotation
+ enable :create_design
+ enable :destroy_design
end
rule { can?(:developer_access) & user_confirmed? }.policy do
@@ -511,6 +519,17 @@ class ProjectPolicy < BasePolicy
rule { admin }.enable :change_repository_storage
+ rule { can?(:read_issue) }.policy do
+ enable :read_design
+ end
+
+ # Design abilities could also be prevented in the issue policy.
+ rule { design_management_disabled }.policy do
+ prevent :read_design
+ prevent :create_design
+ prevent :destroy_design
+ end
+
private
def team_member?
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 8c272a73d40..99c4fc0d1b6 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -68,6 +68,7 @@
= csrf_meta_tags
= csp_meta_tag
+ = action_cable_meta_tag
- unless browser.safari?
%meta{ name: 'referrer', content: 'origin-when-cross-origin' }
diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml
index da20fee227a..e912198be3f 100644
--- a/app/views/projects/cycle_analytics/show.html.haml
+++ b/app/views/projects/cycle_analytics/show.html.haml
@@ -5,6 +5,9 @@
%banner{ "v-if" => "!isOverviewDialogDismissed",
"documentation-link": help_page_path('user/analytics/value_stream_analytics.md'),
"v-on:dismiss-overview-dialog" => "dismissOverviewDialog()" }
+ .mb-3
+ %h3
+ = _("Value Stream Analytics")
%gl-loading-icon{ "v-show" => "isLoading", "size" => "lg" }
.wrapper{ "v-show" => "!isLoading && !hasError" }
.card
diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml
index b5a27f2f17d..4192ecd2238 100644
--- a/app/views/shared/issuable/_sidebar_assignees.html.haml
+++ b/app/views/shared/issuable/_sidebar_assignees.html.haml
@@ -1,7 +1,7 @@
- issuable_type = issuable_sidebar[:type]
- signed_in = !!issuable_sidebar.dig(:current_user, :id)
-#js-vue-sidebar-assignees{ data: { field: "#{issuable_type}", signed_in: signed_in } }
+#js-vue-sidebar-assignees{ data: { field: issuable_type, signed_in: signed_in } }
.title.hide-collapsed
= _('Assignee')
.spinner.spinner-sm.align-bottom