summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets')
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_canceled.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_created.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_failed.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_manual.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_not_found.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_pending.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_running.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_skipped.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_success.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_warning.icobin0 -> 5430 bytes
-rw-r--r--app/assets/javascripts/awards_handler.js3
-rw-r--r--app/assets/javascripts/blob/3d_viewer/index.js147
-rw-r--r--app/assets/javascripts/blob/3d_viewer/mesh_object.js49
-rw-r--r--app/assets/javascripts/blob/pdf/index.js2
-rw-r--r--app/assets/javascripts/blob/stl_viewer.js19
-rw-r--r--app/assets/javascripts/build.js1
-rw-r--r--app/assets/javascripts/dispatcher.js2
-rw-r--r--app/assets/javascripts/environments/components/environment_actions.js2
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js31
-rw-r--r--app/assets/javascripts/merge_request_widget.js7
-rw-r--r--app/assets/javascripts/monitoring/prometheus_graph.js67
-rw-r--r--app/assets/javascripts/pipelines.js4
-rw-r--r--app/assets/stylesheets/framework/awards.scss58
-rw-r--r--app/assets/stylesheets/framework/files.scss6
-rw-r--r--app/assets/stylesheets/framework/modal.scss6
-rw-r--r--app/assets/stylesheets/framework/variables.scss2
-rw-r--r--app/assets/stylesheets/pages/environments.scss9
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss2
-rw-r--r--app/assets/stylesheets/pages/notes.scss41
-rw-r--r--app/assets/stylesheets/pages/profile.scss8
-rw-r--r--app/assets/stylesheets/pages/settings_ci_cd.scss2
-rw-r--r--app/assets/stylesheets/pages/tree.scss2
32 files changed, 438 insertions, 32 deletions
diff --git a/app/assets/images/ci_favicons/icon_status_canceled.ico b/app/assets/images/ci_favicons/icon_status_canceled.ico
new file mode 100755
index 00000000000..5a19458f2a2
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_canceled.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_created.ico b/app/assets/images/ci_favicons/icon_status_created.ico
new file mode 100755
index 00000000000..4dca9640cb3
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_created.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_failed.ico b/app/assets/images/ci_favicons/icon_status_failed.ico
new file mode 100755
index 00000000000..c961ff9a69b
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_failed.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_manual.ico b/app/assets/images/ci_favicons/icon_status_manual.ico
new file mode 100755
index 00000000000..5fbbc99ea7c
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_manual.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_not_found.ico b/app/assets/images/ci_favicons/icon_status_not_found.ico
new file mode 100755
index 00000000000..21afa9c72e6
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_not_found.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_pending.ico b/app/assets/images/ci_favicons/icon_status_pending.ico
new file mode 100755
index 00000000000..8be32dab85a
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_pending.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_running.ico b/app/assets/images/ci_favicons/icon_status_running.ico
new file mode 100755
index 00000000000..f328ff1a5ed
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_running.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_skipped.ico b/app/assets/images/ci_favicons/icon_status_skipped.ico
new file mode 100755
index 00000000000..b4394e1b4af
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_skipped.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_success.ico b/app/assets/images/ci_favicons/icon_status_success.ico
new file mode 100755
index 00000000000..4f436c95242
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_success.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_warning.ico b/app/assets/images/ci_favicons/icon_status_warning.ico
new file mode 100755
index 00000000000..805cc20cdec
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_warning.ico
Binary files differ
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js
index 4f63c7988f5..67106e85a37 100644
--- a/app/assets/javascripts/awards_handler.js
+++ b/app/assets/javascripts/awards_handler.js
@@ -263,7 +263,8 @@ AwardsHandler.prototype.addAward = function addAward(
this.addAwardToEmojiBar(votesBlock, normalizedEmoji, checkMutuality);
return typeof callback === 'function' ? callback() : undefined;
});
- return $('.emoji-menu').removeClass('is-visible');
+ $('.emoji-menu').removeClass('is-visible');
+ $('.js-add-award.is-active').removeClass('is-active');
};
AwardsHandler.prototype.addAwardToEmojiBar = function addAwardToEmojiBar(
diff --git a/app/assets/javascripts/blob/3d_viewer/index.js b/app/assets/javascripts/blob/3d_viewer/index.js
new file mode 100644
index 00000000000..68d4ddad551
--- /dev/null
+++ b/app/assets/javascripts/blob/3d_viewer/index.js
@@ -0,0 +1,147 @@
+import * as THREE from 'three/build/three.module';
+import STLLoaderClass from 'three-stl-loader';
+import OrbitControlsClass from 'three-orbit-controls';
+import MeshObject from './mesh_object';
+
+const STLLoader = STLLoaderClass(THREE);
+const OrbitControls = OrbitControlsClass(THREE);
+
+export default class Renderer {
+ constructor(container) {
+ this.renderWrapper = this.render.bind(this);
+ this.objects = [];
+
+ this.container = container;
+ this.width = this.container.offsetWidth;
+ this.height = 500;
+
+ this.loader = new STLLoader();
+
+ this.fov = 45;
+ this.camera = new THREE.PerspectiveCamera(
+ this.fov,
+ this.width / this.height,
+ 1,
+ 1000,
+ );
+
+ this.scene = new THREE.Scene();
+
+ this.scene.add(this.camera);
+
+ // Setup the viewer
+ this.setupRenderer();
+ this.setupGrid();
+ this.setupLight();
+
+ // Setup OrbitControls
+ this.controls = new OrbitControls(
+ this.camera,
+ this.renderer.domElement,
+ );
+ this.controls.minDistance = 5;
+ this.controls.maxDistance = 30;
+ this.controls.enableKeys = false;
+
+ this.loadFile();
+ }
+
+ setupRenderer() {
+ this.renderer = new THREE.WebGLRenderer({
+ antialias: true,
+ });
+
+ this.renderer.setClearColor(0xFFFFFF);
+ this.renderer.setPixelRatio(window.devicePixelRatio);
+ this.renderer.setSize(
+ this.width,
+ this.height,
+ );
+ }
+
+ setupLight() {
+ // Point light illuminates the object
+ const pointLight = new THREE.PointLight(
+ 0xFFFFFF,
+ 2,
+ 0,
+ );
+
+ pointLight.castShadow = true;
+
+ this.camera.add(pointLight);
+
+ // Ambient light illuminates the scene
+ const ambientLight = new THREE.AmbientLight(
+ 0xFFFFFF,
+ 1,
+ );
+ this.scene.add(ambientLight);
+ }
+
+ setupGrid() {
+ this.grid = new THREE.GridHelper(
+ 20,
+ 20,
+ 0x000000,
+ 0x000000,
+ );
+
+ this.scene.add(this.grid);
+ }
+
+ loadFile() {
+ this.loader.load(this.container.dataset.endpoint, (geo) => {
+ const obj = new MeshObject(geo);
+
+ this.objects.push(obj);
+ this.scene.add(obj);
+
+ this.start();
+ this.setDefaultCameraPosition();
+ });
+ }
+
+ start() {
+ // Empty the container first
+ this.container.innerHTML = '';
+
+ // Add to DOM
+ this.container.appendChild(this.renderer.domElement);
+
+ // Make controls visible
+ this.container.parentNode.classList.remove('is-stl-loading');
+
+ this.render();
+ }
+
+ render() {
+ this.renderer.render(
+ this.scene,
+ this.camera,
+ );
+
+ requestAnimationFrame(this.renderWrapper);
+ }
+
+ changeObjectMaterials(type) {
+ this.objects.forEach((obj) => {
+ obj.changeMaterial(type);
+ });
+ }
+
+ setDefaultCameraPosition() {
+ const obj = this.objects[0];
+ const radius = (obj.geometry.boundingSphere.radius / 1.5);
+ const dist = radius / (Math.sin((this.fov * (Math.PI / 180)) / 2));
+
+ this.camera.position.set(
+ 0,
+ dist + 1,
+ dist,
+ );
+
+ this.camera.lookAt(this.grid);
+ this.controls.update();
+ }
+}
diff --git a/app/assets/javascripts/blob/3d_viewer/mesh_object.js b/app/assets/javascripts/blob/3d_viewer/mesh_object.js
new file mode 100644
index 00000000000..96758884abf
--- /dev/null
+++ b/app/assets/javascripts/blob/3d_viewer/mesh_object.js
@@ -0,0 +1,49 @@
+import {
+ Matrix4,
+ MeshLambertMaterial,
+ Mesh,
+} from 'three/build/three.module';
+
+const defaultColor = 0xE24329;
+const materials = {
+ default: new MeshLambertMaterial({
+ color: defaultColor,
+ }),
+ wireframe: new MeshLambertMaterial({
+ color: defaultColor,
+ wireframe: true,
+ }),
+};
+
+export default class MeshObject extends Mesh {
+ constructor(geo) {
+ super(
+ geo,
+ materials.default,
+ );
+
+ this.geometry.computeBoundingSphere();
+
+ this.rotation.set(-Math.PI / 2, 0, 0);
+
+ if (this.geometry.boundingSphere.radius > 4) {
+ const scale = 4 / this.geometry.boundingSphere.radius;
+
+ this.geometry.applyMatrix(
+ new Matrix4().makeScale(
+ scale,
+ scale,
+ scale,
+ ),
+ );
+ this.geometry.computeBoundingSphere();
+
+ this.position.x = -this.geometry.boundingSphere.center.x;
+ this.position.z = this.geometry.boundingSphere.center.y;
+ }
+ }
+
+ changeMaterial(type) {
+ this.material = materials[type];
+ }
+}
diff --git a/app/assets/javascripts/blob/pdf/index.js b/app/assets/javascripts/blob/pdf/index.js
index 5b79717d1e1..a74c2db9a61 100644
--- a/app/assets/javascripts/blob/pdf/index.js
+++ b/app/assets/javascripts/blob/pdf/index.js
@@ -10,7 +10,7 @@ Vue.use(PDFLab, {
export default () => {
const el = document.getElementById('js-pdf-viewer');
- new Vue({
+ return new Vue({
el,
data() {
return {
diff --git a/app/assets/javascripts/blob/stl_viewer.js b/app/assets/javascripts/blob/stl_viewer.js
new file mode 100644
index 00000000000..f611c4fe640
--- /dev/null
+++ b/app/assets/javascripts/blob/stl_viewer.js
@@ -0,0 +1,19 @@
+import Renderer from './3d_viewer';
+
+document.addEventListener('DOMContentLoaded', () => {
+ const viewer = new Renderer(document.getElementById('js-stl-viewer'));
+
+ [].slice.call(document.querySelectorAll('.js-material-changer')).forEach((el) => {
+ el.addEventListener('click', (e) => {
+ const target = e.target;
+
+ e.preventDefault();
+
+ document.querySelector('.js-material-changer.active').classList.remove('active');
+ target.classList.add('active');
+ target.blur();
+
+ viewer.changeObjectMaterials(target.dataset.type);
+ });
+ });
+});
diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js
index 6efd26ccc37..fe54ecffdfe 100644
--- a/app/assets/javascripts/build.js
+++ b/app/assets/javascripts/build.js
@@ -88,6 +88,7 @@ window.Build = (function() {
dataType: 'json',
success: function(buildData) {
$('.js-build-output').html(buildData.trace_html);
+ gl.utils.setCiStatusFavicon(`${this.pageUrl}/status.json`);
if (window.location.hash === DOWN_BUILD_TRACE) {
$("html,body").scrollTop(this.$buildTrace.height());
}
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 2e7c9bc2689..d1c07891675 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -227,9 +227,11 @@ const ShortcutsBlob = require('./shortcuts_blob');
case 'projects:pipelines:builds':
case 'projects:pipelines:show':
const { controllerAction } = document.querySelector('.js-pipeline-container').dataset;
+ const pipelineStatusUrl = `${document.querySelector('.js-pipeline-tab-link a').getAttribute('href')}/status.json`;
new gl.Pipelines({
initTabs: true,
+ pipelineStatusUrl,
tabsOptions: {
action: controllerAction,
defaultAction: 'pipelines',
diff --git a/app/assets/javascripts/environments/components/environment_actions.js b/app/assets/javascripts/environments/components/environment_actions.js
index 4bb7920bb5e..1418e8d86ee 100644
--- a/app/assets/javascripts/environments/components/environment_actions.js
+++ b/app/assets/javascripts/environments/components/environment_actions.js
@@ -75,6 +75,7 @@ export default {
class="fa fa-spinner fa-spin"
aria-hidden="true"/>
</span>
+ </button>
<ul class="dropdown-menu dropdown-menu-align-right">
<li v-for="action in actions">
@@ -91,7 +92,6 @@ export default {
</button>
</li>
</ul>
- </button>
</div>
`,
};
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index 46b80c04e20..e1e6ca25446 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -2,6 +2,8 @@
(function() {
(function(w) {
var base;
+ const faviconEl = document.getElementById('favicon');
+ const originalFavicon = faviconEl ? faviconEl.getAttribute('href') : null;
w.gl || (w.gl = {});
(base = w.gl).utils || (base.utils = {});
w.gl.utils.isInGroupsPage = function() {
@@ -361,5 +363,34 @@
fn(next, stop);
});
};
+
+ w.gl.utils.setFavicon = (iconName) => {
+ if (faviconEl && iconName) {
+ faviconEl.setAttribute('href', `/assets/${iconName}.ico`);
+ }
+ };
+
+ w.gl.utils.resetFavicon = () => {
+ if (faviconEl) {
+ faviconEl.setAttribute('href', originalFavicon);
+ }
+ };
+
+ w.gl.utils.setCiStatusFavicon = (pageUrl) => {
+ $.ajax({
+ url: pageUrl,
+ dataType: 'json',
+ success: function(data) {
+ if (data && data.icon) {
+ gl.utils.setFavicon(`ci_favicons/${data.icon}`);
+ } else {
+ gl.utils.resetFavicon();
+ }
+ },
+ error: function() {
+ gl.utils.resetFavicon();
+ }
+ });
+ };
})(window);
}).call(window);
diff --git a/app/assets/javascripts/merge_request_widget.js b/app/assets/javascripts/merge_request_widget.js
index 0e2af3df071..b0254b17dd2 100644
--- a/app/assets/javascripts/merge_request_widget.js
+++ b/app/assets/javascripts/merge_request_widget.js
@@ -38,11 +38,13 @@ import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
function MergeRequestWidget(opts) {
// Initialize MergeRequestWidget behavior
//
- // check_enable - Boolean, whether to check automerge status
- // merge_check_url - String, URL to use to check automerge status
+ // check_enable - Boolean, whether to check automerge status
+ // merge_check_url - String, URL to use to check automerge status
// ci_status_url - String, URL to use to check CI status
+ // pipeline_status_url - String, URL to use to get CI status for Favicon
//
this.opts = opts;
+ this.opts.pipeline_status_url = `${this.opts.pipeline_status_url}.json`;
this.$widgetBody = $('.mr-widget-body');
$('#modal_merge_info').modal({
show: false
@@ -159,6 +161,7 @@ import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
_this.status = data.status;
_this.hasCi = data.has_ci;
_this.updateMergeButton(_this.status, _this.hasCi);
+ gl.utils.setCiStatusFavicon(_this.opts.pipeline_status_url);
if (data.environments && data.environments.length) _this.renderEnvironments(data.environments);
if (data.status !== _this.opts.ci_status ||
data.sha !== _this.opts.ci_sha ||
diff --git a/app/assets/javascripts/monitoring/prometheus_graph.js b/app/assets/javascripts/monitoring/prometheus_graph.js
index a6ffa0f59de..d82a4eb9642 100644
--- a/app/assets/javascripts/monitoring/prometheus_graph.js
+++ b/app/assets/javascripts/monitoring/prometheus_graph.js
@@ -6,7 +6,10 @@ import statusCodes from '~/lib/utils/http_status';
import { formatRelevantDigits } from '~/lib/utils/number_utils';
import '../flash';
+const prometheusContainer = '.prometheus-container';
+const prometheusParentGraphContainer = '.prometheus-graphs';
const prometheusGraphsContainer = '.prometheus-graph';
+const prometheusStatesContainer = '.prometheus-state';
const metricsEndpoint = 'metrics.json';
const timeFormat = d3.time.format('%H:%M');
const dayFormat = d3.time.format('%b %e, %a');
@@ -14,19 +17,30 @@ const bisectDate = d3.bisector(d => d.time).left;
const extraAddedWidthParent = 100;
class PrometheusGraph {
-
constructor() {
- this.margin = { top: 80, right: 180, bottom: 80, left: 100 };
- this.marginLabelContainer = { top: 40, right: 0, bottom: 40, left: 0 };
- const parentContainerWidth = $(prometheusGraphsContainer).parent().width() +
- extraAddedWidthParent;
- this.originalWidth = parentContainerWidth;
- this.originalHeight = 330;
- this.width = parentContainerWidth - this.margin.left - this.margin.right;
- this.height = this.originalHeight - this.margin.top - this.margin.bottom;
- this.backOffRequestCounter = 0;
- this.configureGraph();
- this.init();
+ const $prometheusContainer = $(prometheusContainer);
+ const hasMetrics = $prometheusContainer.data('has-metrics');
+ this.docLink = $prometheusContainer.data('doc-link');
+ this.integrationLink = $prometheusContainer.data('prometheus-integration');
+
+ $(document).ajaxError(() => {});
+
+ if (hasMetrics) {
+ this.margin = { top: 80, right: 180, bottom: 80, left: 100 };
+ this.marginLabelContainer = { top: 40, right: 0, bottom: 40, left: 0 };
+ const parentContainerWidth = $(prometheusGraphsContainer).parent().width() +
+ extraAddedWidthParent;
+ this.originalWidth = parentContainerWidth;
+ this.originalHeight = 330;
+ this.width = parentContainerWidth - this.margin.left - this.margin.right;
+ this.height = this.originalHeight - this.margin.top - this.margin.bottom;
+ this.backOffRequestCounter = 0;
+ this.configureGraph();
+ this.init();
+ } else {
+ this.state = '.js-getting-started';
+ this.updateState();
+ }
}
createGraph() {
@@ -40,8 +54,19 @@ class PrometheusGraph {
init() {
this.getData().then((metricsResponse) => {
- if (Object.keys(metricsResponse).length === 0) {
- new Flash('Empty metrics', 'alert');
+ let enoughData = true;
+ Object.keys(metricsResponse.metrics).forEach((key) => {
+ let currentKey;
+ if (key === 'cpu_values' || key === 'memory_values') {
+ currentKey = metricsResponse.metrics[key];
+ if (Object.keys(currentKey).length === 0) {
+ enoughData = false;
+ }
+ }
+ });
+ if (!enoughData) {
+ this.state = '.js-loading';
+ this.updateState();
} else {
this.transformData(metricsResponse);
this.createGraph();
@@ -345,14 +370,17 @@ class PrometheusGraph {
}
return resp.metrics;
})
- .catch(() => new Flash('An error occurred while fetching metrics.', 'alert'));
+ .catch(() => {
+ this.state = '.js-unable-to-connect';
+ this.updateState();
+ });
}
transformData(metricsResponse) {
Object.keys(metricsResponse.metrics).forEach((key) => {
if (key === 'cpu_values' || key === 'memory_values') {
const metricValues = (metricsResponse.metrics[key])[0];
- if (typeof metricValues !== 'undefined') {
+ if (metricValues !== undefined) {
this.graphSpecificProperties[key].data = metricValues.values.map(metric => ({
time: new Date(metric[0] * 1000),
value: metric[1],
@@ -361,6 +389,13 @@ class PrometheusGraph {
}
});
}
+
+ updateState() {
+ const $statesContainer = $(prometheusStatesContainer);
+ $(prometheusParentGraphContainer).hide();
+ $(`${this.state}`, $statesContainer).removeClass('hidden');
+ $(prometheusStatesContainer).show();
+ }
}
export default PrometheusGraph;
diff --git a/app/assets/javascripts/pipelines.js b/app/assets/javascripts/pipelines.js
index 9203abefbbc..4252b615887 100644
--- a/app/assets/javascripts/pipelines.js
+++ b/app/assets/javascripts/pipelines.js
@@ -9,6 +9,10 @@ require('./lib/utils/bootstrap_linked_tabs');
new global.LinkedTabs(options.tabsOptions);
}
+ if (options.pipelineStatusUrl) {
+ gl.utils.setCiStatusFavicon(options.pipelineStatusUrl);
+ }
+
this.addMarginToBuildColumns();
}
diff --git a/app/assets/stylesheets/framework/awards.scss b/app/assets/stylesheets/framework/awards.scss
index 1ae144fb471..b849cc2d853 100644
--- a/app/assets/stylesheets/framework/awards.scss
+++ b/app/assets/stylesheets/framework/awards.scss
@@ -91,7 +91,7 @@
.award-menu-holder {
display: inline-block;
- position: relative;
+ position: absolute;
.tooltip {
white-space: nowrap;
@@ -117,11 +117,41 @@
&.active,
&:hover,
- &:active {
+ &:active,
+ &.is-active {
background-color: $row-hover;
border-color: $row-hover-border;
box-shadow: none;
outline: 0;
+
+ .award-control-icon svg {
+ background: $award-emoji-positive-add-bg;
+
+ path {
+ fill: $award-emoji-positive-add-lines;
+ }
+ }
+
+ .award-control-icon-neutral {
+ opacity: 0;
+ }
+
+ .award-control-icon-positive {
+ opacity: 1;
+ transform: scale(1.15);
+ }
+ }
+
+ &.is-active {
+ .award-control-icon-positive {
+ opacity: 0;
+ transform: scale(1);
+ }
+
+ .award-control-icon-super-positive {
+ opacity: 1;
+ transform: scale(1);
+ }
}
&.btn {
@@ -162,9 +192,33 @@
color: $border-gray-normal;
margin-top: 1px;
padding: 0 2px;
+
+ svg {
+ margin-bottom: 1px;
+ height: 18px;
+ width: 18px;
+ border-radius: 50%;
+
+ path {
+ fill: $border-gray-normal;
+ }
+ }
+ }
+
+ .award-control-icon-positive,
+ .award-control-icon-super-positive {
+ position: absolute;
+ left: 7px;
+ bottom: 9px;
+ opacity: 0;
+ @include transition(opacity, transform);
}
.award-control-text {
vertical-align: middle;
}
}
+
+.note-awards .award-control-icon-positive {
+ left: 6px;
+}
diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss
index ffece53a093..ddea1cf540b 100644
--- a/app/assets/stylesheets/framework/files.scss
+++ b/app/assets/stylesheets/framework/files.scss
@@ -275,3 +275,9 @@ span.idiff {
}
}
}
+
+.is-stl-loading {
+ .stl-controls {
+ display: none;
+ }
+}
diff --git a/app/assets/stylesheets/framework/modal.scss b/app/assets/stylesheets/framework/modal.scss
index 8cd49280e1c..7098203321d 100644
--- a/app/assets/stylesheets/framework/modal.scss
+++ b/app/assets/stylesheets/framework/modal.scss
@@ -16,6 +16,8 @@ body.modal-open {
overflow: hidden;
}
-.modal .modal-dialog {
- width: 860px;
+@media (min-width: $screen-md-min) {
+ .modal-dialog {
+ width: 860px;
+ }
}
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 97794a47df8..712eb7caf33 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -293,6 +293,8 @@ $badge-color: $gl-text-color-secondary;
* Award emoji
*/
$award-emoji-menu-shadow: rgba(0,0,0,.175);
+$award-emoji-positive-add-bg: #fed159;
+$award-emoji-positive-add-lines: #bb9c13;
/*
* Search Box
diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss
index 6faa3794c83..72e7d42858d 100644
--- a/app/assets/stylesheets/pages/environments.scss
+++ b/app/assets/stylesheets/pages/environments.scss
@@ -233,6 +233,15 @@
stroke-width: 1;
}
+.prometheus-state {
+ margin-top: 10px;
+ display: none;
+
+ .state-button-section {
+ margin-top: 10px;
+ }
+}
+
.environments-actions {
.external-url,
.monitoring-url,
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 566dcc64802..2f946ab2f59 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -329,8 +329,6 @@
}
#modal_merge_info .modal-dialog {
- width: 600px;
-
.dark {
margin-right: 40px;
}
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 57cf8e136e2..603ef461ffe 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -398,13 +398,50 @@ ul.notes {
font-size: 17px;
}
- &:hover {
+ svg {
+ height: 16px;
+ width: 16px;
+ fill: $gray-darkest;
+ vertical-align: text-top;
+ }
+
+ .award-control-icon-positive,
+ .award-control-icon-super-positive {
+ position: absolute;
+ margin-left: -20px;
+ opacity: 0;
+ }
+
+ &:hover,
+ &.is-active {
.danger-highlight {
color: $gl-text-red;
}
.link-highlight {
color: $gl-link-color;
+
+ svg {
+ fill: $gl-link-color;
+ }
+ }
+
+ .award-control-icon-neutral {
+ opacity: 0;
+ }
+
+ .award-control-icon-positive {
+ opacity: 1;
+ }
+ }
+
+ &.is-active {
+ .award-control-icon-positive {
+ opacity: 0;
+ }
+
+ .award-control-icon-super-positive {
+ opacity: 1;
}
}
}
@@ -508,7 +545,6 @@ ul.notes {
}
.line-resolve-all-container {
-
.btn-group {
margin-left: -4px;
}
@@ -537,7 +573,6 @@ ul.notes {
fill: $gray-darkest;
}
}
-
}
.line-resolve-all {
diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss
index 703c5fc8869..8c6dd392865 100644
--- a/app/assets/stylesheets/pages/profile.scss
+++ b/app/assets/stylesheets/pages/profile.scss
@@ -230,6 +230,14 @@
font-size: 0;
}
+ .fade-right {
+ right: 0;
+ }
+
+ .fade-left {
+ left: 0;
+ }
+
@media (max-width: $screen-xs-max) {
.cover-block {
padding-top: 20px;
diff --git a/app/assets/stylesheets/pages/settings_ci_cd.scss b/app/assets/stylesheets/pages/settings_ci_cd.scss
index b97a29cd1a0..fe22d186af1 100644
--- a/app/assets/stylesheets/pages/settings_ci_cd.scss
+++ b/app/assets/stylesheets/pages/settings_ci_cd.scss
@@ -6,6 +6,8 @@
}
.trigger-actions {
+ white-space: nowrap;
+
.btn {
margin-left: 10px;
}
diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss
index fc4da4c495f..f3916622b6f 100644
--- a/app/assets/stylesheets/pages/tree.scss
+++ b/app/assets/stylesheets/pages/tree.scss
@@ -145,8 +145,6 @@
margin: 0;
}
-#modal-remove-blob > .modal-dialog { width: 850px; }
-
.blob-upload-dropzone-previews {
text-align: center;
border: 2px;