Merge branch '30469-convdev-index' into 'master'
ConvDev Index Closes #30469 See merge request !11377
4
app/assets/images/i2p-step.svg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 120" enable-background="new 0 0 12 120">
|
||||||
|
<path d="m12 6c0-3.309-2.691-6-6-6s-6 2.691-6 6c0 2.967 2.167 5.431 5 5.91v108.09h2v-108.09c2.833-.479 5-2.943 5-5.91m-6 4c-2.206 0-4-1.794-4-4s1.794-4 4-4 4 1.794 4 4-1.794 4-4 4"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 311 B |
|
@ -393,6 +393,9 @@ import ShortcutsBlob from './shortcuts_blob';
|
||||||
case 'users:show':
|
case 'users:show':
|
||||||
new UserCallout();
|
new UserCallout();
|
||||||
break;
|
break;
|
||||||
|
case 'admin:conversational_development_index:show':
|
||||||
|
new UserCallout();
|
||||||
|
break;
|
||||||
case 'snippets:show':
|
case 'snippets:show':
|
||||||
new LineHighlighter();
|
new LineHighlighter();
|
||||||
new BlobViewer();
|
new BlobViewer();
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
|
|
||||||
const USER_CALLOUT_COOKIE = 'user_callout_dismissed';
|
|
||||||
|
|
||||||
export default class UserCallout {
|
export default class UserCallout {
|
||||||
constructor() {
|
constructor(className = 'user-callout') {
|
||||||
this.isCalloutDismissed = Cookies.get(USER_CALLOUT_COOKIE);
|
this.userCalloutBody = $(`.${className}`);
|
||||||
this.userCalloutBody = $('.user-callout');
|
this.cookieName = this.userCalloutBody.data('uid');
|
||||||
|
this.isCalloutDismissed = Cookies.get(this.cookieName);
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +17,7 @@ export default class UserCallout {
|
||||||
dismissCallout(e) {
|
dismissCallout(e) {
|
||||||
const $currentTarget = $(e.currentTarget);
|
const $currentTarget = $(e.currentTarget);
|
||||||
|
|
||||||
Cookies.set(USER_CALLOUT_COOKIE, 'true', { expires: 365 });
|
Cookies.set(this.cookieName, 'true', { expires: 365 });
|
||||||
|
|
||||||
if ($currentTarget.hasClass('close')) {
|
if ($currentTarget.hasClass('close')) {
|
||||||
this.userCalloutBody.remove();
|
this.userCalloutBody.remove();
|
||||||
|
|
|
@ -569,3 +569,10 @@ $filter-value-selected-color: #d7d7d7;
|
||||||
Animation Functions
|
Animation Functions
|
||||||
*/
|
*/
|
||||||
$dropdown-animation-timing: cubic-bezier(0.23, 1, 0.32, 1);
|
$dropdown-animation-timing: cubic-bezier(0.23, 1, 0.32, 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convdev Index
|
||||||
|
*/
|
||||||
|
$color-high-score: $green-400;
|
||||||
|
$color-average-score: $orange-400;
|
||||||
|
$color-low-score: $red-400;
|
||||||
|
|
255
app/assets/stylesheets/pages/convdev_index.scss
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
$space-between-cards: 8px;
|
||||||
|
|
||||||
|
.convdev-empty svg {
|
||||||
|
margin: 64px auto 32px;
|
||||||
|
max-width: 420px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-header {
|
||||||
|
margin-top: $gl-padding;
|
||||||
|
margin-bottom: $gl-padding;
|
||||||
|
padding: 0 4px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.convdev-header-title {
|
||||||
|
font-size: 48px;
|
||||||
|
line-height: 1;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-header-subtitle {
|
||||||
|
font-size: 22px;
|
||||||
|
line-height: 1;
|
||||||
|
color: $gl-text-color-secondary;
|
||||||
|
margin-left: 8px;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: 18px;
|
||||||
|
color: $gl-text-color-secondary;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $blue-500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-cards {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-card-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
text-align: center;
|
||||||
|
width: 50%;
|
||||||
|
border-color: $border-color;
|
||||||
|
margin: 0 0 32px;
|
||||||
|
padding: $space-between-cards / 2;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
@media (min-width: $screen-xs-min) {
|
||||||
|
width: percentage(1 / 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: $screen-sm-min) {
|
||||||
|
width: percentage(1 / 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: $screen-md-min) {
|
||||||
|
width: percentage(1 / 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: $screen-lg-min) {
|
||||||
|
width: percentage(1 / 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-card {
|
||||||
|
border: solid 1px $border-color;
|
||||||
|
border-radius: 3px;
|
||||||
|
border-top-width: 3px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-card-low {
|
||||||
|
border-top-color: $color-low-score;
|
||||||
|
|
||||||
|
.card-score-big {
|
||||||
|
background-color: $red-25;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-card-average {
|
||||||
|
border-top-color: $color-average-score;
|
||||||
|
|
||||||
|
.card-score-big {
|
||||||
|
background-color: $orange-25;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-card-high {
|
||||||
|
border-top-color: $color-high-score;
|
||||||
|
|
||||||
|
.card-score-big {
|
||||||
|
background-color: $green-25;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-card-title {
|
||||||
|
margin: $gl-padding auto auto;
|
||||||
|
max-width: 100px;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-light {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.25;
|
||||||
|
color: $gl-text-color-secondary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-scores {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
margin: $gl-padding $gl-btn-padding;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-score {
|
||||||
|
color: $gl-text-color-secondary;
|
||||||
|
|
||||||
|
.card-score-name {
|
||||||
|
font-size: 13px;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-score-value {
|
||||||
|
font-size: 16px;
|
||||||
|
color: $gl-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-score-big {
|
||||||
|
border-top: 2px solid $border-color;
|
||||||
|
border-bottom: 1px solid $border-color;
|
||||||
|
font-size: 22px;
|
||||||
|
padding: 10px 0;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-buttons {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
font-size: 16px;
|
||||||
|
color: $gl-text-color-secondary;
|
||||||
|
padding: 10px;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $border-color;
|
||||||
|
color: $gl-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ * {
|
||||||
|
border-left: solid 1px $border-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-steps {
|
||||||
|
margin-top: $gl-padding;
|
||||||
|
height: 1px;
|
||||||
|
min-width: 100%;
|
||||||
|
justify-content: space-around;
|
||||||
|
position: relative;
|
||||||
|
background: $border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-step {
|
||||||
|
$step-positions: 5% 10% 30% 42% 48% 55% 60% 70% 75% 90%;
|
||||||
|
@each $pos in $step-positions {
|
||||||
|
$i: index($step-positions, $pos);
|
||||||
|
|
||||||
|
&:nth-child(#{$i}) {
|
||||||
|
left: $pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
transform-origin: 75% 50%;
|
||||||
|
padding: 8px;
|
||||||
|
height: 50px;
|
||||||
|
width: 50px;
|
||||||
|
border-radius: 3px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
border: solid 1px $border-color;
|
||||||
|
background: $white-light;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
color: $gl-text-color-secondary;
|
||||||
|
fill: $gl-text-color-secondary;
|
||||||
|
box-shadow: 0 2px 4px $dropdown-shadow-color;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
padding: 8px 10px;
|
||||||
|
fill: currentColor;
|
||||||
|
z-index: 100;
|
||||||
|
height: auto;
|
||||||
|
width: auto;
|
||||||
|
|
||||||
|
.convdev-step-title {
|
||||||
|
max-height: 2em;
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
transform: scale(1.5);
|
||||||
|
margin: $gl-btn-padding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
transition: transform 0.1s;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
min-height: 30px;
|
||||||
|
min-width: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-step-title {
|
||||||
|
max-height: 0;
|
||||||
|
opacity: 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin: $gl-vert-padding 0 0;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-high-score {
|
||||||
|
color: $color-high-score;
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-average-score {
|
||||||
|
color: $color-average-score;
|
||||||
|
}
|
||||||
|
|
||||||
|
.convdev-low-score {
|
||||||
|
color: $color-low-score;
|
||||||
|
}
|
|
@ -287,6 +287,7 @@ table.u2f-registrations {
|
||||||
|
|
||||||
.user-callout {
|
.user-callout {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
max-width: $screen-lg-min;
|
||||||
|
|
||||||
.bordered-box {
|
.bordered-box {
|
||||||
border: 1px solid $blue-300;
|
border: 1px solid $blue-300;
|
||||||
|
@ -295,14 +296,15 @@ table.u2f-registrations {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.landing {
|
.landing {
|
||||||
margin-top: $gl-padding;
|
padding: 32px;
|
||||||
margin-bottom: $gl-padding;
|
|
||||||
|
|
||||||
.close {
|
.close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
|
||||||
|
@ -330,11 +332,20 @@ table.u2f-registrations {
|
||||||
height: 110px;
|
height: 110px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.convdev {
|
||||||
|
margin: 0 0 0 30px;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
height: 127px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-callout-copy {
|
.user-callout-copy {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
|
max-width: 570px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,12 +359,20 @@ table.u2f-registrations {
|
||||||
.landing {
|
.landing {
|
||||||
.svg-container,
|
.svg-container,
|
||||||
.user-callout-copy {
|
.user-callout-copy {
|
||||||
margin: 0;
|
margin: 0 auto;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
height: 75px;
|
height: 75px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.convdev {
|
||||||
|
margin: $gl-padding auto 0;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
height: 120px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class Admin::ConversationalDevelopmentIndexController < Admin::ApplicationController
|
||||||
|
def show
|
||||||
|
@metric = ConversationalDevelopmentIndex::Metric.order(:created_at).last&.present
|
||||||
|
end
|
||||||
|
end
|
|
@ -275,8 +275,8 @@ module ApplicationHelper
|
||||||
'active' if condition
|
'active' if condition
|
||||||
end
|
end
|
||||||
|
|
||||||
def show_user_callout?
|
def show_callout?(name)
|
||||||
cookies[:user_callout_dismissed].nil?
|
cookies[name] != 'true'
|
||||||
end
|
end
|
||||||
|
|
||||||
def linkedin_url(user)
|
def linkedin_url(user)
|
||||||
|
|
16
app/helpers/conversational_development_index_helper.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
module ConversationalDevelopmentIndexHelper
|
||||||
|
def score_level(score)
|
||||||
|
if score < 33.33
|
||||||
|
'low'
|
||||||
|
elsif score < 66.66
|
||||||
|
'average'
|
||||||
|
else
|
||||||
|
'high'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def format_score(score)
|
||||||
|
precision = score < 1 ? 2 : 1
|
||||||
|
number_with_precision(score, precision: precision)
|
||||||
|
end
|
||||||
|
end
|
26
app/models/conversational_development_index/card.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
module ConversationalDevelopmentIndex
|
||||||
|
class Card
|
||||||
|
attr_accessor :metric, :title, :description, :feature, :blog, :docs
|
||||||
|
|
||||||
|
def initialize(metric:, title:, description:, feature:, blog:, docs: nil)
|
||||||
|
self.metric = metric
|
||||||
|
self.title = title
|
||||||
|
self.description = description
|
||||||
|
self.feature = feature
|
||||||
|
self.blog = blog
|
||||||
|
self.docs = docs
|
||||||
|
end
|
||||||
|
|
||||||
|
def instance_score
|
||||||
|
metric.instance_score(feature)
|
||||||
|
end
|
||||||
|
|
||||||
|
def leader_score
|
||||||
|
metric.leader_score(feature)
|
||||||
|
end
|
||||||
|
|
||||||
|
def percentage_score
|
||||||
|
metric.percentage_score(feature)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
module ConversationalDevelopmentIndex
|
||||||
|
class IdeaToProductionStep
|
||||||
|
attr_accessor :metric, :title, :features
|
||||||
|
|
||||||
|
def initialize(metric:, title:, features:)
|
||||||
|
self.metric = metric
|
||||||
|
self.title = title
|
||||||
|
self.features = features
|
||||||
|
end
|
||||||
|
|
||||||
|
def percentage_score
|
||||||
|
sum = features.sum do |feature|
|
||||||
|
metric.percentage_score(feature)
|
||||||
|
end
|
||||||
|
|
||||||
|
sum / features.size.to_f
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
21
app/models/conversational_development_index/metric.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
module ConversationalDevelopmentIndex
|
||||||
|
class Metric < ActiveRecord::Base
|
||||||
|
include Presentable
|
||||||
|
|
||||||
|
self.table_name = 'conversational_development_index_metrics'
|
||||||
|
|
||||||
|
def instance_score(feature)
|
||||||
|
self["instance_#{feature}"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def leader_score(feature)
|
||||||
|
self["leader_#{feature}"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def percentage_score(feature)
|
||||||
|
return 100 if leader_score(feature).zero?
|
||||||
|
|
||||||
|
100 * instance_score(feature) / leader_score(feature)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,144 @@
|
||||||
|
module ConversationalDevelopmentIndex
|
||||||
|
class MetricPresenter < Gitlab::View::Presenter::Simple
|
||||||
|
def cards
|
||||||
|
[
|
||||||
|
Card.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Issues',
|
||||||
|
description: 'created per active user',
|
||||||
|
feature: 'issues',
|
||||||
|
blog: 'https://www2.deloitte.com/content/dam/Deloitte/se/Documents/technology-media-telecommunications/deloitte-digital-collaboration.pdf'
|
||||||
|
),
|
||||||
|
Card.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Comments',
|
||||||
|
description: 'created per active user',
|
||||||
|
feature: 'notes',
|
||||||
|
blog: 'http://conversationaldevelopment.com/why/'
|
||||||
|
),
|
||||||
|
Card.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Milestones',
|
||||||
|
description: 'created per active user',
|
||||||
|
feature: 'milestones',
|
||||||
|
blog: 'http://conversationaldevelopment.com/shorten-cycle/',
|
||||||
|
docs: help_page_path('user/project/milestones/index')
|
||||||
|
),
|
||||||
|
Card.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Boards',
|
||||||
|
description: 'created per active user',
|
||||||
|
feature: 'boards',
|
||||||
|
blog: 'http://jpattonassociates.com/user-story-mapping/',
|
||||||
|
docs: help_page_path('user/project/issue_board')
|
||||||
|
),
|
||||||
|
Card.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Merge Requests',
|
||||||
|
description: 'per active user',
|
||||||
|
feature: 'merge_requests',
|
||||||
|
blog: 'https://8thlight.com/blog/uncle-bob/2013/02/01/The-Humble-Craftsman.html',
|
||||||
|
docs: help_page_path('user/project/merge_requests/index')
|
||||||
|
),
|
||||||
|
Card.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Pipelines',
|
||||||
|
description: 'created per active user',
|
||||||
|
feature: 'ci_pipelines',
|
||||||
|
blog: 'https://martinfowler.com/bliki/ContinuousDelivery.html',
|
||||||
|
docs: help_page_path('ci/README')
|
||||||
|
),
|
||||||
|
Card.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Environments',
|
||||||
|
description: 'created per active user',
|
||||||
|
feature: 'environments',
|
||||||
|
blog: 'https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/',
|
||||||
|
docs: help_page_path('ci/environments')
|
||||||
|
),
|
||||||
|
Card.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Deployments',
|
||||||
|
description: 'created per active user',
|
||||||
|
feature: 'deployments',
|
||||||
|
blog: 'https://puppet.com/blog/continuous-delivery-vs-continuous-deployment-what-s-diff'
|
||||||
|
),
|
||||||
|
Card.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Monitoring',
|
||||||
|
description: 'fraction of all projects',
|
||||||
|
feature: 'projects_prometheus_active',
|
||||||
|
blog: 'https://prometheus.io/docs/introduction/overview/',
|
||||||
|
docs: help_page_path('user/project/integrations/prometheus')
|
||||||
|
),
|
||||||
|
Card.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Service Desk',
|
||||||
|
description: 'issues created per active user',
|
||||||
|
feature: 'service_desk_issues',
|
||||||
|
blog: 'http://blogs.forrester.com/kate_leggett/17-01-30-top_trends_for_customer_service_in_2017_operations_become_smarter_and_more_strategic',
|
||||||
|
docs: 'https://docs.gitlab.com/ee/user/project/service_desk.html'
|
||||||
|
)
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def idea_to_production_steps
|
||||||
|
[
|
||||||
|
IdeaToProductionStep.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Idea',
|
||||||
|
features: %w(issues)
|
||||||
|
),
|
||||||
|
IdeaToProductionStep.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Issue',
|
||||||
|
features: %w(issues notes)
|
||||||
|
),
|
||||||
|
IdeaToProductionStep.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Plan',
|
||||||
|
features: %w(milestones boards)
|
||||||
|
),
|
||||||
|
IdeaToProductionStep.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Code',
|
||||||
|
features: %w(merge_requests)
|
||||||
|
),
|
||||||
|
IdeaToProductionStep.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Commit',
|
||||||
|
features: %w(merge_requests)
|
||||||
|
),
|
||||||
|
IdeaToProductionStep.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Test',
|
||||||
|
features: %w(ci_pipelines)
|
||||||
|
),
|
||||||
|
IdeaToProductionStep.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Review',
|
||||||
|
features: %w(ci_pipelines environments)
|
||||||
|
),
|
||||||
|
IdeaToProductionStep.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Staging',
|
||||||
|
features: %w(environments deployments)
|
||||||
|
),
|
||||||
|
IdeaToProductionStep.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Production',
|
||||||
|
features: %w(deployments)
|
||||||
|
),
|
||||||
|
IdeaToProductionStep.new(
|
||||||
|
metric: subject,
|
||||||
|
title: 'Feedback',
|
||||||
|
features: %w(projects_prometheus_active service_desk_issues)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def average_percentage_score
|
||||||
|
cards.sum(&:percentage_score) / cards.size.to_f
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
41
app/services/submit_usage_ping_service.rb
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
class SubmitUsagePingService
|
||||||
|
URL = 'https://version.gitlab.com/usage_data'.freeze
|
||||||
|
|
||||||
|
include Gitlab::CurrentSettings
|
||||||
|
|
||||||
|
def execute
|
||||||
|
return false unless current_application_settings.usage_ping_enabled?
|
||||||
|
|
||||||
|
response = HTTParty.post(
|
||||||
|
URL,
|
||||||
|
body: Gitlab::UsageData.to_json(force_refresh: true),
|
||||||
|
headers: { 'Content-type' => 'application/json' }
|
||||||
|
)
|
||||||
|
|
||||||
|
store_metrics(response)
|
||||||
|
|
||||||
|
true
|
||||||
|
rescue HTTParty::Error => e
|
||||||
|
Rails.logger.info "Unable to contact GitLab, Inc.: #{e}"
|
||||||
|
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def store_metrics(response)
|
||||||
|
return unless response['conv_index'].present?
|
||||||
|
|
||||||
|
ConversationalDevelopmentIndex::Metric.create!(
|
||||||
|
response['conv_index'].slice(
|
||||||
|
'leader_issues', 'instance_issues', 'leader_notes', 'instance_notes',
|
||||||
|
'leader_milestones', 'instance_milestones', 'leader_boards', 'instance_boards',
|
||||||
|
'leader_merge_requests', 'instance_merge_requests', 'leader_ci_pipelines',
|
||||||
|
'instance_ci_pipelines', 'leader_environments', 'instance_environments',
|
||||||
|
'leader_deployments', 'instance_deployments', 'leader_projects_prometheus_active',
|
||||||
|
'instance_projects_prometheus_active', 'leader_service_desk_issues',
|
||||||
|
'instance_service_desk_issues'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,6 @@
|
||||||
- @no_container = true
|
- @no_container = true
|
||||||
- page_title "Background Jobs"
|
- page_title "Background Jobs"
|
||||||
= render 'admin/background_jobs/head'
|
= render 'admin/monitoring/head'
|
||||||
|
|
||||||
%div{ class: container_class }
|
%div{ class: container_class }
|
||||||
%h3.page-title Background Jobs
|
%h3.page-title Background Jobs
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
.prepend-top-default
|
||||||
|
.user-callout{ data: { uid: 'convdev_intro_callout_dismissed' } }
|
||||||
|
.bordered-box.landing.content-block
|
||||||
|
%button.btn.btn-default.close.js-close-callout{ type: 'button',
|
||||||
|
'aria-label' => 'Dismiss ConvDev introduction' }
|
||||||
|
= icon('times', class: 'dismiss-icon', 'aria-hidden' => 'true')
|
||||||
|
.user-callout-copy
|
||||||
|
%h4
|
||||||
|
Introducing Your Conversational Development Index
|
||||||
|
%p
|
||||||
|
Your Conversational Development Index gives an overview of how you are using GitLab from a feature perspective. View how you compare with other organizations, discover features you are not using, and learn best practices through blog posts and white papers.
|
||||||
|
.svg-container.convdev
|
||||||
|
= custom_icon('convdev_overview')
|
|
@ -0,0 +1,25 @@
|
||||||
|
.convdev-card-wrapper
|
||||||
|
.convdev-card{ class: "convdev-card-#{score_level(card.percentage_score)}" }
|
||||||
|
.convdev-card-title
|
||||||
|
%h3
|
||||||
|
= card.title
|
||||||
|
.text-light
|
||||||
|
= card.description
|
||||||
|
.card-scores
|
||||||
|
.card-score
|
||||||
|
.card-score-value
|
||||||
|
= format_score(card.instance_score)
|
||||||
|
.card-score-name You
|
||||||
|
.card-score
|
||||||
|
.card-score-value
|
||||||
|
= format_score(card.leader_score)
|
||||||
|
.card-score-name Lead
|
||||||
|
.card-score-big
|
||||||
|
= number_to_percentage(card.percentage_score, precision: 1)
|
||||||
|
.card-buttons
|
||||||
|
- if card.blog
|
||||||
|
%a{ href: card.blog }
|
||||||
|
= icon('info-circle', 'aria-hidden' => 'true')
|
||||||
|
- if card.docs
|
||||||
|
%a{ href: card.docs }
|
||||||
|
= icon('question-circle', 'aria-hidden' => 'true')
|
|
@ -0,0 +1,9 @@
|
||||||
|
.container.convdev-empty
|
||||||
|
.col-sm-6.col-sm-push-3.text-center
|
||||||
|
= custom_icon('convdev_no_index')
|
||||||
|
%h4 Usage ping is not enabled
|
||||||
|
%p
|
||||||
|
ConvDev is only shown when the
|
||||||
|
= link_to 'usage ping', help_page_path('user/admin_area/settings/usage_statistics'), target: '_blank'
|
||||||
|
is enabled. Enable usage ping to get an overview of how you are using GitLab from a feature perspective
|
||||||
|
= link_to 'Enable usage ping', admin_application_settings_path(anchor: 'usage-statistics'), class: 'btn btn-primary'
|
|
@ -0,0 +1,7 @@
|
||||||
|
.container.convdev-empty
|
||||||
|
.col-sm-6.col-sm-push-3.text-center
|
||||||
|
= custom_icon('convdev_no_data')
|
||||||
|
%h4 Data is still calculating...
|
||||||
|
%p
|
||||||
|
In order to gather accurate feature usage data, it can take 1 to 2 weeks to see your index.
|
||||||
|
= link_to 'Learn more', help_page_path('user/admin_area/monitoring/convdev'), target: '_blank'
|
|
@ -0,0 +1,35 @@
|
||||||
|
- @no_container = true
|
||||||
|
- page_title 'ConvDev Index'
|
||||||
|
|
||||||
|
= render 'admin/monitoring/head'
|
||||||
|
|
||||||
|
.container
|
||||||
|
- if show_callout?('convdev_intro_callout_dismissed')
|
||||||
|
= render 'callout'
|
||||||
|
|
||||||
|
.prepend-top-default
|
||||||
|
- if !current_application_settings.usage_ping_enabled
|
||||||
|
= render 'disabled'
|
||||||
|
- elsif @metric.blank?
|
||||||
|
= render 'no_data'
|
||||||
|
- else
|
||||||
|
.convdev
|
||||||
|
.convdev-header
|
||||||
|
%h2.convdev-header-title{ class: "convdev-#{score_level(@metric.average_percentage_score)}-score" }
|
||||||
|
= number_to_percentage(@metric.average_percentage_score, precision: 1)
|
||||||
|
.convdev-header-subtitle
|
||||||
|
index
|
||||||
|
%br
|
||||||
|
score
|
||||||
|
= link_to icon('question-circle', 'aria-hidden' => 'true'), help_page_path('user/admin_area/monitoring/convdev')
|
||||||
|
|
||||||
|
.convdev-cards.card-container
|
||||||
|
- @metric.cards.each do |card|
|
||||||
|
= render 'card', card: card
|
||||||
|
|
||||||
|
.convdev-steps.visible-lg
|
||||||
|
- @metric.idea_to_production_steps.each_with_index do |step, index|
|
||||||
|
.convdev-step{ class: "convdev-#{score_level(step.percentage_score)}-score" }
|
||||||
|
= custom_icon("i2p_step_#{index + 1}")
|
||||||
|
%h4.convdev-step-title
|
||||||
|
= step.title
|
|
@ -1,6 +1,6 @@
|
||||||
- @no_container = true
|
- @no_container = true
|
||||||
- page_title "Health Check"
|
- page_title "Health Check"
|
||||||
= render 'admin/background_jobs/head'
|
= render 'admin/monitoring/head'
|
||||||
|
|
||||||
%div{ class: container_class }
|
%div{ class: container_class }
|
||||||
%h3.page-title
|
%h3.page-title
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
- loggers = [Gitlab::GitLogger, Gitlab::AppLogger,
|
- loggers = [Gitlab::GitLogger, Gitlab::AppLogger,
|
||||||
Gitlab::EnvironmentLogger, Gitlab::SidekiqLogger,
|
Gitlab::EnvironmentLogger, Gitlab::SidekiqLogger,
|
||||||
Gitlab::RepositoryCheckLogger]
|
Gitlab::RepositoryCheckLogger]
|
||||||
= render 'admin/background_jobs/head'
|
= render 'admin/monitoring/head'
|
||||||
|
|
||||||
%div{ class: container_class }
|
%div{ class: container_class }
|
||||||
%ul.nav-links.log-tabs
|
%ul.nav-links.log-tabs
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
= render 'shared/nav_scroll'
|
= render 'shared/nav_scroll'
|
||||||
.nav-links.sub-nav.scrolling-tabs
|
.nav-links.sub-nav.scrolling-tabs
|
||||||
%ul{ class: (container_class) }
|
%ul{ class: (container_class) }
|
||||||
|
= nav_link(controller: :conversational_development_index) do
|
||||||
|
= link_to admin_conversational_development_index_path, title: 'ConvDev Index' do
|
||||||
|
%span
|
||||||
|
ConvDev Index
|
||||||
= nav_link(controller: :system_info) do
|
= nav_link(controller: :system_info) do
|
||||||
= link_to admin_system_info_path, title: 'System Info' do
|
= link_to admin_system_info_path, title: 'System Info' do
|
||||||
%span
|
%span
|
|
@ -1,6 +1,6 @@
|
||||||
- @no_container = true
|
- @no_container = true
|
||||||
- page_title 'Requests Profiles'
|
- page_title 'Requests Profiles'
|
||||||
= render 'admin/background_jobs/head'
|
= render 'admin/monitoring/head'
|
||||||
|
|
||||||
%div{ class: container_class }
|
%div{ class: container_class }
|
||||||
%h3.page-title
|
%h3.page-title
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
- @no_container = true
|
- @no_container = true
|
||||||
- page_title "System Info"
|
- page_title "System Info"
|
||||||
= render 'admin/background_jobs/head'
|
= render 'admin/monitoring/head'
|
||||||
|
|
||||||
%div{ class: container_class }
|
%div{ class: container_class }
|
||||||
.prepend-top-default
|
.prepend-top-default
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
= render "projects/last_push"
|
= render "projects/last_push"
|
||||||
|
|
||||||
%div{ class: container_class }
|
%div{ class: container_class }
|
||||||
- if show_user_callout?
|
- if show_callout?('user_callout_dismissed')
|
||||||
= render 'shared/user_callout'
|
= render 'shared/user_callout'
|
||||||
|
|
||||||
- if @projects.any? || params[:name]
|
- if @projects.any? || params[:name]
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
= link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do
|
= link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do
|
||||||
%span
|
%span
|
||||||
Overview
|
Overview
|
||||||
= nav_link(controller: %w(system_info background_jobs logs health_check requests_profiles)) do
|
= nav_link(controller: %w(conversational_development_index system_info background_jobs logs health_check requests_profiles)) do
|
||||||
= link_to admin_system_info_path, title: 'Monitoring' do
|
= link_to admin_conversational_development_index_path, title: 'Monitoring' do
|
||||||
%span
|
%span
|
||||||
Monitoring
|
Monitoring
|
||||||
= nav_link(controller: :broadcast_messages) do
|
= nav_link(controller: :broadcast_messages) do
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.user-callout
|
.user-callout{ data: { uid: 'user_callout_dismissed' } }
|
||||||
.bordered-box.landing.content-block
|
.bordered-box.landing.content-block
|
||||||
%button.btn.btn-default.close.js-close-callout{ type: 'button',
|
%button.btn.btn-default.close.js-close-callout{ type: 'button',
|
||||||
'aria-label' => 'Dismiss customize experience box' }
|
'aria-label' => 'Dismiss customize experience box' }
|
||||||
|
|
40
app/views/shared/icons/_convdev_no_data.svg
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="220" viewBox="0 0 360 220">
|
||||||
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<path fill="#000" fill-opacity=".02" d="M125 44V24.003C125 18.48 129.483 14 135.005 14h89.99C230.52 14 235 18.477 235 24.003V43h84.992C326.624 43 332 48.372 332 55.002v144.996c0 6.63-5.38 12.002-12.008 12.002h-85.984c-6.632 0-12.008-5.372-12.008-12.002V183h-78v17.002c0 6.626-5.38 11.998-12.008 11.998H46.008C39.376 212 34 206.624 34 200.002V55.998C34 49.372 39.38 44 46.008 44H125z"/>
|
||||||
|
<g transform="translate(214 36)">
|
||||||
|
<rect width="110" height="168" x="2" y="2" fill="#FFF" rx="10"/>
|
||||||
|
<path fill="#EEE" fill-rule="nonzero" d="M4 12.006c0-2.208.896-4.27 2.457-5.77.796-.766.82-2.032.055-2.828-.766-.796-2.032-.82-2.828-.055C1.347 5.6 0 8.7 0 12.006c0 1.105.895 2 2 2s2-.895 2-2zM14.388 4h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm17.51.227c2.115.514 3.93 1.88 5.022 3.756.556.955 1.78 1.28 2.735.724.954-.556 1.278-1.78.723-2.735-1.636-2.813-4.356-4.86-7.534-5.632-1.073-.26-2.155.397-2.416 1.47-.26 1.074.397 2.156 1.47 2.417zM110 16.78v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm-.024 17.844c-.17 2.186-1.227 4.18-2.903 5.558-.853.702-.976 1.962-.275 2.815.7.854 1.962.977 2.815.275 2.51-2.062 4.096-5.056 4.35-8.338.086-1.1-.737-2.063-1.838-2.15-1.102-.084-2.064.74-2.15 1.84zM98.826 168h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-17.334-.4c-2.063-.68-3.77-2.186-4.71-4.143-.477-.996-1.67-1.416-2.667-.938-.996.476-1.416 1.67-.938 2.667 1.41 2.936 3.964 5.19 7.063 6.21 1.05.347 2.18-.223 2.526-1.272.346-1.05-.224-2.18-1.274-2.526zM4 154.434v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2z"/>
|
||||||
|
<path fill="#F0EDF8" fill-rule="nonzero" d="M57 111c-11.598 0-21-9.402-21-21s9.402-21 21-21 21 9.402 21 21-9.402 21-21 21zm0-4c9.39 0 17-7.61 17-17s-7.61-17-17-17-17 7.61-17 17 7.61 17 17 17z"/>
|
||||||
|
<path fill="#6B4FBB" d="M58 88v-6.997c0-1.11-.895-2.003-2-2.003-1.112 0-2 .897-2 2.003v8.994c0 1.11.895 2.003 2 2.003.174 0 .343-.022.503-.063.162.04.33.063.506.063h7.98C66.1 92 67 91.105 67 90c0-1.112-.9-2-2.01-2H58z"/>
|
||||||
|
<rect width="8" height="4" x="8" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<path fill="#EEE" d="M21 16c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C21.895 18 21 17.112 21 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C34.895 18 34 17.112 34 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C47.895 18 47 17.112 47 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C60.895 18 60 17.112 60 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C73.895 18 73 17.112 73 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C86.895 18 86 17.112 86 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C99.895 18 99 17.112 99 16z"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(118 7)">
|
||||||
|
<rect width="110" height="168" x="2" y="2" fill="#FFF" rx="10"/>
|
||||||
|
<path fill="#EEE" fill-rule="nonzero" d="M4 12.006c0-2.208.896-4.27 2.457-5.77.796-.766.82-2.032.055-2.828-.766-.796-2.032-.82-2.828-.055C1.347 5.6 0 8.7 0 12.006c0 1.105.895 2 2 2s2-.895 2-2zM14.388 4h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm17.51.227c2.115.514 3.93 1.88 5.022 3.756.556.955 1.78 1.28 2.735.724.954-.556 1.278-1.78.723-2.735-1.636-2.813-4.356-4.86-7.534-5.632-1.073-.26-2.155.397-2.416 1.47-.26 1.074.397 2.156 1.47 2.417zM110 16.78v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm-.024 17.844c-.17 2.186-1.227 4.18-2.903 5.558-.853.702-.976 1.962-.275 2.815.7.854 1.962.977 2.815.275 2.51-2.062 4.096-5.056 4.35-8.338.086-1.1-.737-2.063-1.838-2.15-1.102-.084-2.064.74-2.15 1.84zM98.826 168h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-17.334-.4c-2.063-.68-3.77-2.186-4.71-4.143-.477-.996-1.67-1.416-2.667-.938-.996.476-1.416 1.67-.938 2.667 1.41 2.936 3.964 5.19 7.063 6.21 1.05.347 2.18-.223 2.526-1.272.346-1.05-.224-2.18-1.274-2.526zM4 154.434v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2z"/>
|
||||||
|
<g fill-rule="nonzero">
|
||||||
|
<path fill="#F0EDF8" d="M57 112c-12.15 0-22-9.85-22-22s9.85-22 22-22 22 9.85 22 22-9.85 22-22 22zm0-6c8.837 0 16-7.163 16-16s-7.163-16-16-16-16 7.163-16 16 7.163 16 16 16z"/>
|
||||||
|
<path fill="#6B4FBB" d="M41.692 105.8C45.768 109.75 51.21 112 57 112c12.15 0 22-9.85 22-22s-9.85-22-22-22v6c8.837 0 16 7.163 16 16s-7.163 16-16 16c-4.215 0-8.166-1.633-11.133-4.508l-4.175 4.31z"/>
|
||||||
|
</g>
|
||||||
|
<path fill="#EEE" d="M8 16c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2H9.998C8.895 18 8 17.112 8 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C21.895 18 21 17.112 21 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C34.895 18 34 17.112 34 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C47.895 18 47 17.112 47 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C60.895 18 60 17.112 60 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C73.895 18 73 17.112 73 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C86.895 18 86 17.112 86 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C99.895 18 99 17.112 99 16z"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(26 36)">
|
||||||
|
<rect width="110" height="168" x="2" y="2" fill="#FFF" rx="10"/>
|
||||||
|
<path fill="#EEE" fill-rule="nonzero" d="M4 12.006v147.988C4 164.42 7.58 168 12.005 168h89.99c4.42 0 8.005-3.586 8.005-8.006V12.006C110 7.58 106.42 4 101.995 4h-89.99C7.585 4 4 7.586 4 12.006zm-4 0C0 5.376 5.377 0 12.005 0h89.99C108.628 0 114 5.37 114 12.006v147.988c0 6.63-5.377 12.006-12.005 12.006h-89.99C5.372 172 0 166.63 0 159.994V12.006z"/>
|
||||||
|
<g transform="translate(21 82)">
|
||||||
|
<rect width="24" height="4" y="10" fill="#F0EDF8" rx="2"/>
|
||||||
|
<rect width="14" height="4" x="5" fill="#6B4FBB" rx="2"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(69 82)">
|
||||||
|
<rect width="24" height="4" y="10" fill="#F0EDF8" rx="2"/>
|
||||||
|
<rect width="14" height="4" x="5" fill="#6B4FBB" rx="2"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(38 42)">
|
||||||
|
<rect width="22" height="4" x="8" fill="#FEE1D3" rx="2"/>
|
||||||
|
<rect width="38" height="4" y="12" fill="#FB722E" rx="2"/>
|
||||||
|
</g>
|
||||||
|
<path fill="#EEE" d="M4 14h106v4H4z"/>
|
||||||
|
<path fill="#333" d="M35.724 138h9.696v-2.856h-2.856V122.76h-2.592c-1.08.648-2.136 1.08-3.792 1.392v2.184h2.856v8.808h-3.312V138zm17.736.288c-2.952 0-5.76-2.208-5.76-7.56 0-5.688 2.952-8.256 6.168-8.256 2.016 0 3.48.84 4.44 1.824l-1.848 2.112c-.528-.576-1.488-1.08-2.376-1.08-1.68 0-3.024 1.2-3.144 4.752.792-1.008 2.112-1.608 3.048-1.608 2.616 0 4.536 1.488 4.536 4.704 0 3.168-2.304 5.112-5.064 5.112zm-.072-2.64c1.056 0 1.92-.744 1.92-2.472 0-1.608-.84-2.208-1.992-2.208-.792 0-1.68.432-2.304 1.512.312 2.4 1.32 3.168 2.376 3.168zM63.9 132c-2.256 0-3.888-1.848-3.888-4.992 0-3.12 1.632-4.944 3.888-4.944 2.256 0 3.912 1.824 3.912 4.944 0 3.144-1.656 4.992-3.912 4.992zm0-1.968c.792 0 1.44-.792 1.44-3.024s-.648-2.976-1.44-2.976c-.792 0-1.44.744-1.44 2.976s.648 3.024 1.44 3.024zm.528 8.256l8.448-16.224h2.04l-8.448 16.224h-2.04zm11.016 0c-2.256 0-3.888-1.848-3.888-4.992 0-3.12 1.632-4.944 3.888-4.944 2.256 0 3.912 1.824 3.912 4.944 0 3.144-1.656 4.992-3.912 4.992zm0-1.968c.792 0 1.44-.792 1.44-3.024s-.648-2.976-1.44-2.976c-.792 0-1.44.744-1.44 2.976s.648 3.024 1.44 3.024z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 11 KiB |
67
app/views/shared/icons/_convdev_no_index.svg
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="200" viewBox="0 0 360 200">
|
||||||
|
<g fill="none" fill-rule="evenodd" transform="translate(3 11)">
|
||||||
|
<rect width="110" height="168" x="6" y="8" fill="#000" fill-opacity=".02" rx="10"/>
|
||||||
|
<g transform="translate(0 2)">
|
||||||
|
<rect width="110" height="168" fill="#FFF" rx="10"/>
|
||||||
|
<path fill="#EEE" fill-rule="nonzero" d="M2 10.006v147.988C2 162.42 5.58 166 10.005 166h89.99c4.42 0 8.005-3.586 8.005-8.006V10.006C108 5.58 104.42 2 99.995 2h-89.99C5.585 2 2 5.586 2 10.006zm-4 0C-2 3.376 3.377-2 10.005-2h89.99C106.628-2 112 3.37 112 10.006v147.988c0 6.63-5.377 12.006-12.005 12.006h-89.99C3.372 170-2 164.63-2 157.994V10.006z"/>
|
||||||
|
<g transform="translate(19 80)">
|
||||||
|
<rect width="24" height="4" y="10" fill="#F0EDF8" rx="2"/>
|
||||||
|
<rect width="14" height="4" x="5" fill="#6B4FBB" rx="2"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(67 80)">
|
||||||
|
<rect width="24" height="4" y="10" fill="#F0EDF8" rx="2"/>
|
||||||
|
<rect width="14" height="4" x="5" fill="#6B4FBB" rx="2"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(36 40)">
|
||||||
|
<rect width="22" height="4" x="8" fill="#FEE1D3" rx="2"/>
|
||||||
|
<rect width="38" height="4" y="12" fill="#FB722E" rx="2"/>
|
||||||
|
</g>
|
||||||
|
<path fill="#EEE" d="M2 12h106v4H2z"/>
|
||||||
|
<path fill="#333" d="M38.048 127.792c.792 0 1.68-.432 2.28-1.512-.312-2.4-1.296-3.168-2.376-3.168-1.032 0-1.92.744-1.92 2.472 0 1.608.864 2.208 2.016 2.208zm-.552 8.496c-2.016 0-3.504-.864-4.464-1.824l1.872-2.112c.504.576 1.464 1.08 2.352 1.08 1.704 0 3.024-1.2 3.144-4.752-.792 1.008-2.112 1.608-3.048 1.608-2.592 0-4.536-1.488-4.536-4.704 0-3.168 2.304-5.112 5.064-5.112 2.952 0 5.784 2.208 5.784 7.56 0 5.688-2.976 8.256-6.168 8.256zm13.488 0c-3.048 0-5.304-1.704-5.304-4.176 0-1.848 1.152-2.976 2.592-3.744v-.096c-1.176-.888-2.04-1.992-2.04-3.6 0-2.592 2.04-4.2 4.872-4.2 2.784 0 4.632 1.656 4.632 4.176 0 1.464-.936 2.64-1.992 3.336v.096c1.464.792 2.64 1.968 2.64 3.984 0 2.4-2.16 4.224-5.4 4.224zm.96-9.168c.6-.696.936-1.44.936-2.232 0-1.176-.696-1.968-1.848-1.968-.936 0-1.704.576-1.704 1.752 0 1.248 1.056 1.848 2.616 2.448zm-.888 6.72c1.176 0 2.04-.624 2.04-1.896 0-1.344-1.296-1.848-3.216-2.664-.672.624-1.176 1.488-1.176 2.424 0 1.344 1.08 2.136 2.352 2.136zm10.8-3.84c-2.256 0-3.888-1.848-3.888-4.992 0-3.12 1.632-4.944 3.888-4.944 2.256 0 3.912 1.824 3.912 4.944 0 3.144-1.656 4.992-3.912 4.992zm0-1.968c.792 0 1.44-.792 1.44-3.024s-.648-2.976-1.44-2.976c-.792 0-1.44.744-1.44 2.976s.648 3.024 1.44 3.024zm.528 8.256l8.448-16.224h2.04l-8.448 16.224h-2.04zm11.016 0c-2.256 0-3.888-1.848-3.888-4.992 0-3.12 1.632-4.944 3.888-4.944 2.256 0 3.912 1.824 3.912 4.944 0 3.144-1.656 4.992-3.912 4.992zm0-1.968c.792 0 1.44-.792 1.44-3.024s-.648-2.976-1.44-2.976c-.792 0-1.44.744-1.44 2.976s.648 3.024 1.44 3.024z"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(122)">
|
||||||
|
<rect width="110" height="168" x="2" y="2" fill="#FFF" rx="10"/>
|
||||||
|
<path fill="#EEE" fill-rule="nonzero" d="M4 12.006c0-2.208.896-4.27 2.457-5.77.796-.766.82-2.032.055-2.828-.766-.796-2.032-.82-2.828-.055C1.347 5.6 0 8.7 0 12.006c0 1.105.895 2 2 2s2-.895 2-2zM14.388 4h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm17.51.227c2.115.514 3.93 1.88 5.022 3.756.556.955 1.78 1.28 2.735.724.954-.556 1.278-1.78.723-2.735-1.636-2.813-4.356-4.86-7.534-5.632-1.073-.26-2.155.397-2.416 1.47-.26 1.074.397 2.156 1.47 2.417zM110 16.78v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm-.024 17.844c-.17 2.186-1.227 4.18-2.903 5.558-.853.702-.976 1.962-.275 2.815.7.854 1.962.977 2.815.275 2.51-2.062 4.096-5.056 4.35-8.338.086-1.1-.737-2.063-1.838-2.15-1.102-.084-2.064.74-2.15 1.84zM98.826 168h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-17.334-.4c-2.063-.68-3.77-2.186-4.71-4.143-.477-.996-1.67-1.416-2.667-.938-.996.476-1.416 1.67-.938 2.667 1.41 2.936 3.964 5.19 7.063 6.21 1.05.347 2.18-.223 2.526-1.272.346-1.05-.224-2.18-1.274-2.526zM4 154.434v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2z"/>
|
||||||
|
<g transform="translate(21 82)">
|
||||||
|
<rect width="24" height="4" y="10" fill="#F0EDF8" rx="2"/>
|
||||||
|
<rect width="14" height="4" x="5" fill="#C3B8E3" rx="2"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(69 82)">
|
||||||
|
<rect width="24" height="4" y="10" fill="#F0EDF8" rx="2"/>
|
||||||
|
<rect width="14" height="4" x="5" fill="#C3B8E3" rx="2"/>
|
||||||
|
</g>
|
||||||
|
<path fill="#FEE1D3" d="M44 44c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C44.894 46 44 45.112 44 44zm10 0c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C54.894 46 54 45.112 54 44zm10 0c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C64.894 46 64 45.112 64 44zM34 56c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C34.894 58 34 57.112 34 56zm10 0c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C44.894 58 44 57.112 44 56zm10 0c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C54.894 58 54 57.112 54 56zm10 0c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C64.894 58 64 57.112 64 56zm10 0c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C74.894 58 74 57.112 74 56z"/>
|
||||||
|
<rect width="8" height="4" x="8" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="21" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="34" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="47" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="60" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="73" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="86" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="99" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<path fill="#EEE" d="M46.716 138.288c-3.264 0-5.448-2.784-5.448-7.968s2.184-7.848 5.448-7.848c3.264 0 5.448 2.664 5.448 7.848 0 5.184-2.184 7.968-5.448 7.968zm0-2.736c1.2 0 2.112-1.08 2.112-5.232 0-4.176-.912-5.112-2.112-5.112-1.176 0-2.112.936-2.112 5.112 0 4.152.936 5.232 2.112 5.232zM57.564 132c-2.256 0-3.888-1.848-3.888-4.992 0-3.12 1.632-4.944 3.888-4.944 2.256 0 3.912 1.824 3.912 4.944 0 3.144-1.656 4.992-3.912 4.992zm0-1.968c.792 0 1.44-.792 1.44-3.024s-.648-2.976-1.44-2.976c-.792 0-1.44.744-1.44 2.976s.648 3.024 1.44 3.024zm.528 8.256l8.448-16.224h2.04l-8.448 16.224h-2.04zm11.016 0c-2.256 0-3.888-1.848-3.888-4.992 0-3.12 1.632-4.944 3.888-4.944 2.256 0 3.912 1.824 3.912 4.944 0 3.144-1.656 4.992-3.912 4.992zm0-1.968c.792 0 1.44-.792 1.44-3.024s-.648-2.976-1.44-2.976c-.792 0-1.44.744-1.44 2.976s.648 3.024 1.44 3.024z"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(243)">
|
||||||
|
<rect width="110" height="168" x="2" y="2" fill="#FFF" rx="10"/>
|
||||||
|
<path fill="#EEE" fill-rule="nonzero" d="M4 12.006c0-2.208.896-4.27 2.457-5.77.796-.766.82-2.032.055-2.828-.766-.796-2.032-.82-2.828-.055C1.347 5.6 0 8.7 0 12.006c0 1.105.895 2 2 2s2-.895 2-2zM14.388 4h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm17.51.227c2.115.514 3.93 1.88 5.022 3.756.556.955 1.78 1.28 2.735.724.954-.556 1.278-1.78.723-2.735-1.636-2.813-4.356-4.86-7.534-5.632-1.073-.26-2.155.397-2.416 1.47-.26 1.074.397 2.156 1.47 2.417zM110 16.78v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm-.024 17.844c-.17 2.186-1.227 4.18-2.903 5.558-.853.702-.976 1.962-.275 2.815.7.854 1.962.977 2.815.275 2.51-2.062 4.096-5.056 4.35-8.338.086-1.1-.737-2.063-1.838-2.15-1.102-.084-2.064.74-2.15 1.84zM98.826 168h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-17.334-.4c-2.063-.68-3.77-2.186-4.71-4.143-.477-.996-1.67-1.416-2.667-.938-.996.476-1.416 1.67-.938 2.667 1.41 2.936 3.964 5.19 7.063 6.21 1.05.347 2.18-.223 2.526-1.272.346-1.05-.224-2.18-1.274-2.526zM4 154.434v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2z"/>
|
||||||
|
<path fill="#FEE1D3" d="M44 44c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C44.894 46 44 45.112 44 44zm10 0c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C54.894 46 54 45.112 54 44zm10 0c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C64.894 46 64 45.112 64 44zM34 56c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C34.894 58 34 57.112 34 56zm10 0c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C44.894 58 44 57.112 44 56zm10 0c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C54.894 58 54 57.112 54 56zm10 0c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C64.894 58 64 57.112 64 56zm10 0c0-1.105.898-2 1.998-2h2.004c1.104 0 1.998.888 1.998 2 0 1.105-.898 2-1.998 2h-2.004C74.894 58 74 57.112 74 56z"/>
|
||||||
|
<g transform="translate(21 82)">
|
||||||
|
<rect width="24" height="4" y="10" fill="#F0EDF8" rx="2"/>
|
||||||
|
<rect width="14" height="4" x="5" fill="#C3B8E3" rx="2"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(69 82)">
|
||||||
|
<rect width="24" height="4" y="10" fill="#F0EDF8" rx="2"/>
|
||||||
|
<rect width="14" height="4" x="5" fill="#C3B8E3" rx="2"/>
|
||||||
|
</g>
|
||||||
|
<rect width="8" height="4" x="8" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="21" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="34" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="47" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="60" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="73" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="86" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<rect width="8" height="4" x="99" y="14" fill="#EEE" rx="2"/>
|
||||||
|
<path fill="#EEE" d="M46.716 138.288c-3.264 0-5.448-2.784-5.448-7.968s2.184-7.848 5.448-7.848c3.264 0 5.448 2.664 5.448 7.848 0 5.184-2.184 7.968-5.448 7.968zm0-2.736c1.2 0 2.112-1.08 2.112-5.232 0-4.176-.912-5.112-2.112-5.112-1.176 0-2.112.936-2.112 5.112 0 4.152.936 5.232 2.112 5.232zM57.564 132c-2.256 0-3.888-1.848-3.888-4.992 0-3.12 1.632-4.944 3.888-4.944 2.256 0 3.912 1.824 3.912 4.944 0 3.144-1.656 4.992-3.912 4.992zm0-1.968c.792 0 1.44-.792 1.44-3.024s-.648-2.976-1.44-2.976c-.792 0-1.44.744-1.44 2.976s.648 3.024 1.44 3.024zm.528 8.256l8.448-16.224h2.04l-8.448 16.224h-2.04zm11.016 0c-2.256 0-3.888-1.848-3.888-4.992 0-3.12 1.632-4.944 3.888-4.944 2.256 0 3.912 1.824 3.912 4.944 0 3.144-1.656 4.992-3.912 4.992zm0-1.968c.792 0 1.44-.792 1.44-3.024s-.648-2.976-1.44-2.976c-.792 0-1.44.744-1.44 2.976s.648 3.024 1.44 3.024z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 14 KiB |
64
app/views/shared/icons/_convdev_overview.svg
Normal file
After Width: | Height: | Size: 15 KiB |
12
app/views/shared/icons/_i2p_step_1.svg
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 76 76" enable-background="new 0 0 76 76">
|
||||||
|
<path d="m45.688 18.854c-4.869-1.989-10.488-1.975-15.29-.001-2.413.979-4.597 2.414-6.493 4.268-1.836 1.8-3.33 3.985-4.346 6.381-1.013 2.38-1.525 4.916-1.525 7.537 0 2.066.33 4.118.983 6.104.469 1.388 1.089 2.706 1.83 3.937-1.275 1.101-2.086 2.725-2.086 4.538 0 3.309 2.691 6 6 6s6-2.691 6-6-2.691-6-6-6c-.779 0-1.522.154-2.205.425-.665-1.105-1.221-2.289-1.642-3.533-.585-1.776-.881-3.618-.881-5.472 0-2.351.459-4.623 1.391-6.814.89-2.096 2.231-4.059 3.88-5.675 1.708-1.669 3.675-2.962 5.85-3.845 4.329-1.778 9.392-1.79 13.78.002 2.17.881 4.137 2.175 5.843 3.84 3.39 3.34 5.257 7.776 5.257 12.493.002 1.86-.294 3.705-.878 5.481-.579 1.75-1.443 3.406-2.569 4.923-2.134 2.866-3.818 4.698-5.174 6.173-2.424 2.643-3.98 4.599-4.383 8.384h-10.815c-.553 0-1 .447-1 1s.447 1 1 1h11.739c.532 0 .971-.416.999-.947.19-3.645 1.345-5.263 3.934-8.09 1.385-1.506 3.107-3.381 5.304-6.331 1.254-1.688 2.218-3.535 2.864-5.489.651-1.98.98-4.04.979-6.109 0-5.256-2.078-10.198-5.856-13.92-1.897-1.851-4.081-3.287-6.49-4.265m-16.927 32.763c0 2.206-1.794 4-4 4s-4-1.794-4-4 1.794-4 4-4 4 1.794 4 4"/>
|
||||||
|
<path d="m40 74h-4c-.553 0-1 .447-1 1s.447 1 1 1h4c.553 0 1-.447 1-1s-.447-1-1-1"/>
|
||||||
|
<path d="m42 70h-8c-.553 0-1 .447-1 1s.447 1 1 1h8c.553 0 1-.447 1-1s-.447-1-1-1"/>
|
||||||
|
<path d="m38 10c.553 0 1-.447 1-1v-8c0-.553-.447-1-1-1s-1 .447-1 1v8c0 .553.447 1 1 1"/>
|
||||||
|
<path d="m20.828 15.828c.256 0 .512-.098.707-.293.391-.391.391-1.023 0-1.414l-5.656-5.656c-.391-.391-1.023-.391-1.414 0s-.391 1.023 0 1.414l5.656 5.656c.195.195.451.293.707.293"/>
|
||||||
|
<path d="m10 33h-8c-.553 0-1 .447-1 1s.447 1 1 1h8c.553 0 1-.447 1-1s-.447-1-1-1"/>
|
||||||
|
<path d="m60.12 8.465l-5.656 5.656c-.391.391-.391 1.023 0 1.414.195.195.451.293.707.293s.512-.098.707-.293l5.656-5.656c.391-.391.391-1.023 0-1.414s-1.023-.391-1.414 0"/>
|
||||||
|
<path d="m74 33h-8c-.553 0-1 .447-1 1s.447 1 1 1h8c.553 0 1-.447 1-1s-.447-1-1-1"/>
|
||||||
|
<path d="m43 66h-10c-.553 0-1 .447-1 1s.447 1 1 1h10c.553 0 1-.447 1-1s-.447-1-1-1"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2 KiB |
12
app/views/shared/icons/_i2p_step_10.svg
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 76 76" enable-background="new 0 0 76 76">
|
||||||
|
<path d="m5 43c0 .553.447 1 1 1s1-.447 1-1v-4h4c.553 0 1-.447 1-1s-.447-1-1-1h-4v-4c0-.553-.447-1-1-1s-1 .447-1 1v4h-4c-.553 0-1 .447-1 1s.447 1 1 1h4v4"/>
|
||||||
|
<path d="m75 37h-4v-4c0-.553-.447-1-1-1s-1 .447-1 1v4h-4c-.553 0-1 .447-1 1s.447 1 1 1h4v4c0 .553.447 1 1 1s1-.447 1-1v-4h4c.553 0 1-.447 1-1s-.447-1-1-1"/>
|
||||||
|
<path d="m21 38c0 .345.178.665.47.848l8 5c.165.103.348.152.529.152.333 0 .659-.166.849-.47.293-.469.15-1.086-.317-1.378l-6.644-4.152 6.644-4.152c.468-.292.61-.909.317-1.378s-.908-.611-1.378-.317l-8 5c-.292.182-.47.502-.47.847"/>
|
||||||
|
<path d="m55 38c0-.345-.178-.665-.47-.848l-8-5c-.469-.294-1.086-.151-1.378.317-.293.469-.15 1.086.317 1.378l6.644 4.153-6.644 4.152c-.468.292-.61.909-.317 1.378.189.304.516.47.849.47.181 0 .364-.049.529-.152l8-5c.292-.183.47-.503.47-.848"/>
|
||||||
|
<path d="m41.803 26.05c-.525-.168-1.089.124-1.256.65l-7 22c-.167.525.124 1.088.65 1.256.101.032.202.047.303.047.424 0 .817-.271.953-.697l7-22c.167-.526-.124-1.088-.65-1.256"/>
|
||||||
|
<path d="m62 7c3.859 0 7 3.141 7 7v11c0 .553.447 1 1 1s1-.447 1-1v-11c0-4.963-4.04-9-9-9h-16.09c-.479-2.833-2.943-5-5.91-5-3.309 0-6 2.691-6 6s2.691 6 6 6c2.967 0 5.431-2.167 5.91-5h16.09m-22 3c-2.206 0-4-1.794-4-4s1.794-4 4-4 4 1.794 4 4-1.794 4-4 4"/>
|
||||||
|
<path d="m6 26c.553 0 1-.447 1-1v-11c0-3.859 3.141-7 7-7h11.09l-3.293 3.293c-.391.391-.391 1.023 0 1.414.195.195.451.293.707.293s.512-.098.707-.293l5-5c.391-.391.391-1.023 0-1.414l-5-5c-.391-.391-1.023-.391-1.414 0s-.391 1.023 0 1.414l3.293 3.293h-11.09c-4.963 0-9 4.04-9 9v11c0 .553.447 1 1 1"/>
|
||||||
|
<path d="m36 64c-2.967 0-5.431 2.167-5.91 5h-16.09c-3.859 0-7-3.141-7-7v-11c0-.553-.447-1-1-1s-1 .447-1 1v11c0 4.963 4.04 9 9 9h16.09c.478 2.833 2.942 5 5.91 5 3.309 0 6-2.691 6-6s-2.691-6-6-6m0 10c-2.206 0-4-1.794-4-4s1.794-4 4-4 4 1.794 4 4-1.794 4-4 4"/>
|
||||||
|
<path d="m70 50c-.553 0-1 .447-1 1v11c0 3.859-3.141 7-7 7h-11.09l3.293-3.293c.391-.391.391-1.023 0-1.414s-1.023-.391-1.414 0l-5 5c-.391.391-.391 1.023 0 1.414l5 5c.195.195.451.293.707.293s.512-.098.707-.293c.391-.391.391-1.023 0-1.414l-3.293-3.293h11.09c4.963 0 9-4.04 9-9v-11c0-.553-.447-1-1-1"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
5
app/views/shared/icons/_i2p_step_2.svg
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 76 76" enable-background="new 0 0 76 76">
|
||||||
|
<path d="m42.26 40.44c.558.073 1.045-.329 1.109-.877l2.625-22.444c.033-.283-.057-.567-.246-.781-.189-.214-.462-.336-.747-.336h-14c-.284 0-.555.121-.744.332-.19.212-.281.494-.25.776l3.454 31.575c-1.503 1.285-2.46 3.19-2.46 5.317 0 3.859 3.141 7 7 7s7-3.141 7-7-3.141-7-7-7c-.94 0-1.835.189-2.655.527l-3.23-29.527h11.761l-2.494 21.328c-.065.549.328 1.045.877 1.11m.741 13.562c0 2.757-2.243 5-5 5s-5-2.243-5-5 2.243-5 5-5 5 2.243 5 5"/>
|
||||||
|
<path d="M73.236,23.749c-0.207-0.513-0.796-0.76-1.302-0.552c-0.513,0.207-0.759,0.79-0.552,1.302 C73.119,28.787,74,33.329,74,38c0,19.851-16.149,36-36,36S2,57.851,2,38S18.149,2,38,2c7.6,0,14.83,2.332,20.965,6.74 C58.339,9.702,58,10.825,58,12c0,1.603,0.624,3.109,1.758,4.242C60.891,17.376,62.397,18,64,18c1.603,0,3.109-0.624,4.242-1.758 C69.376,15.109,70,13.603,70,12s-0.624-3.109-1.758-4.242C67.109,6.624,65.603,6,64,6c-1.346,0-2.622,0.445-3.668,1.259 C53.812,2.512,46.104,0,38,0C17.047,0,0,17.047,0,38s17.047,38,38,38s38-17.047,38-38C76,33.07,75.07,28.275,73.236,23.749z M64,8 c1.068,0,2.072,0.416,2.828,1.172S68,10.932,68,12s-0.416,2.072-1.172,2.828c-1.512,1.512-4.145,1.512-5.656,0 C60.416,14.072,60,13.068,60,12s0.416-2.072,1.172-2.828S62.932,8,64,8z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
12
app/views/shared/icons/_i2p_step_3.svg
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 76 76" enable-background="new 0 0 76 76">
|
||||||
|
<path d="m12 8c0-3.309-2.691-6-6-6s-6 2.691-6 6c0 2.967 2.167 5.431 5 5.91v8.181c-2.833.478-5 2.942-5 5.909s2.167 5.431 5 5.91v8.181c-2.833.478-5 2.942-5 5.909s2.167 5.431 5 5.91v8.181c-2.833.478-5 2.942-5 5.909 0 3.309 2.691 6 6 6s6-2.691 6-6c0-2.967-2.167-5.431-5-5.91v-8.18c2.833-.478 5-2.942 5-5.91s-2.167-5.431-5-5.91v-8.18c2.833-.478 5-2.942 5-5.91s-2.167-5.431-5-5.91v-8.18c2.833-.479 5-2.943 5-5.91m-10 0c0-2.206 1.794-4 4-4s4 1.794 4 4-1.794 4-4 4-4-1.794-4-4m8 60c0 2.206-1.794 4-4 4s-4-1.794-4-4 1.794-4 4-4 4 1.794 4 4m0-20c0 2.206-1.794 4-4 4s-4-1.794-4-4 1.794-4 4-4 4 1.794 4 4m0-20c0 2.206-1.794 4-4 4s-4-1.794-4-4 1.794-4 4-4 4 1.794 4 4"/>
|
||||||
|
<path d="m21 6h54c.553 0 1-.447 1-1s-.447-1-1-1h-54c-.553 0-1 .447-1 1s.447 1 1 1"/>
|
||||||
|
<path d="m21 12h35c.553 0 1-.447 1-1s-.447-1-1-1h-35c-.553 0-1 .447-1 1s.447 1 1 1"/>
|
||||||
|
<path d="m75 24h-54c-.553 0-1 .447-1 1s.447 1 1 1h54c.553 0 1-.447 1-1s-.447-1-1-1"/>
|
||||||
|
<path d="m21 32h34c.553 0 1-.447 1-1s-.447-1-1-1h-34c-.553 0-1 .447-1 1s.447 1 1 1"/>
|
||||||
|
<path d="m75 44h-54c-.553 0-1 .447-1 1s.447 1 1 1h54c.553 0 1-.447 1-1s-.447-1-1-1"/>
|
||||||
|
<path d="m21 52h34c.553 0 1-.447 1-1s-.447-1-1-1h-34c-.553 0-1 .447-1 1s.447 1 1 1"/>
|
||||||
|
<path d="m75 64h-54c-.553 0-1 .447-1 1s.447 1 1 1h54c.553 0 1-.447 1-1s-.447-1-1-1"/>
|
||||||
|
<path d="m55 70h-34c-.553 0-1 .447-1 1s.447 1 1 1h34c.553 0 1-.447 1-1s-.447-1-1-1"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
6
app/views/shared/icons/_i2p_step_4.svg
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 76 76" enable-background="new 0 0 76 76">
|
||||||
|
<path d="m67.7 10h-6.751c-.507-5.598-5.221-10-10.949-10-6.06 0-11 4.935-11 11s4.935 11 11 11c5.728 0 10.442-4.402 10.949-10h6.751c1.269 0 2.3.987 2.3 2.2v57.6c0 1.213-1.031 2.2-2.3 2.2h-59.4c-1.269 0-2.3-.987-2.3-2.2v-57.6c0-1.213 1.031-2.2 2.3-2.2h15.15c.553 0 1-.447 1-1s-.447-1-1-1h-15.15c-2.371 0-4.3 1.884-4.3 4.2v57.6c0 2.316 1.929 4.2 4.3 4.2h59.4c2.371 0 4.3-1.884 4.3-4.2v-57.6c0-2.316-1.929-4.2-4.3-4.2m-17.7 10c-4.963 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9"/>
|
||||||
|
<path d="m21.293 29.29c-.391.391-.391 1.023 0 1.414l12.975 12.975-12.975 12.974c-.391.391-.391 1.023 0 1.414.195.195.451.293.707.293s.512-.098.707-.293l13.682-13.682c.391-.391.391-1.023 0-1.414l-13.682-13.681c-.391-.391-1.023-.391-1.414 0"/>
|
||||||
|
<path d="m54 59c.553 0 1-.447 1-1s-.447-1-1-1h-12c-.553 0-1 .447-1 1s.447 1 1 1h12"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 936 B |
5
app/views/shared/icons/_i2p_step_5.svg
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 76 76" enable-background="new 0 0 76 76">
|
||||||
|
<path d="m48.949 37c-.507-5.598-5.221-10-10.949-10s-10.442 4.402-10.949 10h-13.05c-.553 0-1 .447-1 1s.447 1 1 1h13.05c.507 5.598 5.221 10 10.949 10s10.442-4.402 10.949-10h12.24c.553 0 1-.447 1-1s-.447-1-1-1h-12.24m-10.949 10c-4.963 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9"/>
|
||||||
|
<path d="M73.236,23.749c-0.207-0.513-0.797-0.76-1.302-0.552c-0.513,0.207-0.759,0.79-0.552,1.302 C73.119,28.787,74,33.329,74,38c0,19.851-16.149,36-36,36S2,57.851,2,38S18.149,2,38,2c7.6,0,14.83,2.332,20.965,6.74 C58.339,9.702,58,10.825,58,12c0,1.603,0.624,3.109,1.758,4.242C60.891,17.376,62.397,18,64,18c1.603,0,3.109-0.624,4.242-1.758 C69.376,15.109,70,13.603,70,12s-0.624-3.109-1.758-4.242C67.109,6.624,65.603,6,64,6c-1.346,0-2.622,0.445-3.668,1.259 C53.812,2.512,46.104,0,38,0C17.047,0,0,17.047,0,38s17.047,38,38,38s38-17.047,38-38C76,33.07,75.07,28.275,73.236,23.749z M64,8 c1.068,0,2.072,0.416,2.828,1.172S68,10.932,68,12s-0.416,2.072-1.172,2.828c-1.512,1.512-4.145,1.512-5.656,0 C60.416,14.072,60,13.068,60,12s0.416-2.072,1.172-2.828S62.932,8,64,8z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
15
app/views/shared/icons/_i2p_step_6.svg
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 76 76" enable-background="new 0 0 76 76">
|
||||||
|
<path d="m14.267 7.32l-4.896 5.277-1.702-1.533c-.409-.369-1.043-.338-1.412.074-.369.41-.337 1.042.074 1.412l2.434 2.192c.064.058.139.091.212.13.035.018.065.048.101.062.114.044.235.066.356.066.135 0 .27-.028.396-.082.044-.019.077-.058.118-.084.076-.047.155-.086.219-.154l5.566-6c.375-.404.352-1.037-.054-1.413-.405-.377-1.036-.353-1.412.053"/>
|
||||||
|
<path d="m31 9h44c.553 0 1-.447 1-1s-.447-1-1-1h-44c-.553 0-1 .447-1 1s.447 1 1 1"/>
|
||||||
|
<path d="m31 15h24c.553 0 1-.447 1-1s-.447-1-1-1h-24c-.553 0-1 .447-1 1s.447 1 1 1"/>
|
||||||
|
<path d="m11 0c-6.07 0-11 4.935-11 11s4.935 11 11 11 11-4.935 11-11-4.935-11-11-11m0 20c-4.963 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9"/>
|
||||||
|
<path d="m14.267 34.32l-4.896 5.277-1.702-1.533c-.409-.368-1.043-.338-1.412.074-.369.41-.337 1.042.074 1.412l2.434 2.192c.064.058.139.091.212.13.035.018.065.048.101.062.114.044.235.066.356.066.135 0 .27-.028.396-.082.044-.019.077-.058.118-.084.076-.047.155-.086.219-.154l5.566-6c.375-.404.352-1.037-.054-1.413-.405-.377-1.036-.353-1.412.053"/>
|
||||||
|
<path d="m75 34h-44c-.553 0-1 .447-1 1s.447 1 1 1h44c.553 0 1-.447 1-1s-.447-1-1-1"/>
|
||||||
|
<path d="m31 42h24c.553 0 1-.447 1-1s-.447-1-1-1h-24c-.553 0-1 .447-1 1s.447 1 1 1"/>
|
||||||
|
<path d="m11 27c-6.07 0-11 4.935-11 11s4.935 11 11 11 11-4.935 11-11-4.935-11-11-11m0 20c-4.963 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9"/>
|
||||||
|
<path d="m14.267 61.32l-4.896 5.277-1.702-1.533c-.409-.368-1.043-.338-1.412.074-.369.41-.337 1.042.074 1.412l2.434 2.192c.064.058.139.091.212.13.035.018.065.048.101.062.114.044.235.066.356.066.135 0 .27-.028.396-.082.044-.019.077-.058.118-.084.076-.047.155-.086.219-.154l5.566-6c.375-.404.352-1.037-.054-1.413-.405-.377-1.036-.353-1.412.053"/>
|
||||||
|
<path d="m11 54c-6.07 0-11 4.935-11 11s4.935 11 11 11 11-4.935 11-11-4.935-11-11-11m0 20c-4.963 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9"/>
|
||||||
|
<path d="m75 61h-44c-.553 0-1 .447-1 1s.447 1 1 1h44c.553 0 1-.447 1-1s-.447-1-1-1"/>
|
||||||
|
<path d="m55 67h-24c-.553 0-1 .447-1 1s.447 1 1 1h24c.553 0 1-.447 1-1s-.447-1-1-1"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
7
app/views/shared/icons/_i2p_step_7.svg
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 76 76" enable-background="new 0 0 76 76">
|
||||||
|
<path d="M73.236,23.749c-0.208-0.513-0.798-0.76-1.302-0.552c-0.513,0.207-0.759,0.79-0.552,1.302 C73.119,28.787,74,33.329,74,38c0,19.851-16.149,36-36,36S2,57.851,2,38S18.149,2,38,2c7.6,0,14.83,2.332,20.965,6.74 C58.339,9.702,58,10.825,58,12c0,1.603,0.624,3.109,1.758,4.242C60.891,17.376,62.397,18,64,18c1.603,0,3.109-0.624,4.242-1.758 C69.376,15.109,70,13.603,70,12s-0.624-3.109-1.758-4.242C67.109,6.624,65.603,6,64,6c-1.346,0-2.622,0.445-3.668,1.259 C53.812,2.512,46.104,0,38,0C17.047,0,0,17.047,0,38s17.047,38,38,38s38-17.047,38-38C76,33.07,75.07,28.275,73.236,23.749z M64,8 c1.068,0,2.072,0.416,2.828,1.172S68,10.932,68,12s-0.416,2.072-1.172,2.828c-1.512,1.512-4.145,1.512-5.656,0 C60.416,14.072,60,13.068,60,12s0.416-2.072,1.172-2.828S62.932,8,64,8z"/>
|
||||||
|
<path d="m27.19 32.17c-.277-.479-.89-.643-1.366-.364l-12.654 7.326c-.309.179-.499.509-.499.865s.19.687.499.865l12.654 7.326c.157.092.33.135.5.135.345 0 .681-.179.866-.499.277-.478.113-1.09-.364-1.366l-11.159-6.461 11.159-6.461c.478-.276.642-.889.364-1.366"/>
|
||||||
|
<path d="m48.808 47.827c.186.32.521.499.866.499.17 0 .343-.043.5-.135l12.654-7.326c.309-.179.499-.509.499-.865s-.19-.687-.499-.865l-12.654-7.326c-.478-.278-1.09-.114-1.366.364-.277.478-.113 1.09.364 1.366l11.159 6.461-11.159 6.461c-.478.276-.642.889-.364 1.366"/>
|
||||||
|
<path d="m42.71 23.06l-11.312 33.23c-.179.522.102 1.091.624 1.269.106.037.216.054.322.054.416 0 .805-.262.946-.678l11.312-33.23c.179-.522-.102-1.091-.624-1.269-.523-.181-1.089.101-1.268.624"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
4
app/views/shared/icons/_i2p_step_8.svg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 76 76" enable-background="new 0 0 76 76">
|
||||||
|
<path d="m62.44 54.765l-9.912-11.09c.315-3.881.481-7.241.508-10.271-.029-13.871-3.789-23.05-13.413-32.746-.855-.859-2.411-.828-3.294.059-7.594 7.65-11.139 13.934-12.575 22.3-1.776.062-3.437.776-4.699 2.039-1.321 1.321-2.05 3.079-2.05 4.949s.729 3.628 2.051 4.949c1.321 1.322 3.079 2.051 4.949 2.051s3.628-.729 4.949-2.051c1.322-1.321 2.051-3.079 2.051-4.949 0-1.869-.729-3.627-2.051-4.949-.9-.9-2-1.517-3.205-1.824 1.373-7.859 4.764-13.818 11.999-21.11.128-.13.356-.158.456-.059 9.207 9.274 12.805 18.06 12.832 31.33-.026 3.079-.202 6.527-.536 10.54-.023.273.067.545.25.749l10.166 11.379c.062.076.109.23.093.32l-4.547 17.407c-.004.015-.009.036-.079.106-.062.063-.155.1-.2.106l-3.577.002c-.144-.009-.265-.077-.309-.153l-5.425-10.328c-.173-.329-.515-.535-.886-.535h-15.962c-.371 0-.713.206-.886.535l-5.407 10.303-.069.072c-.07.07-.165.105-.199.105l-3.588.001c-.179-.009-.304-.123-.33-.227l-4.531-17.338c-.029-.146.019-.301.049-.34l10.197-11.415c.367-.412.332-1.044-.08-1.412-.411-.366-1.042-.333-1.412.08l-10.229 11.453c-.448.554-.63 1.312-.474 2.084l4.544 17.396c.253.963 1.146 1.669 2.218 1.719h3.636c.581 0 1.187-.261 1.615-.693.114-.114.286-.286.406-.528l5.144-9.793h14.754l5.16 9.822c.396.697 1.124 1.143 2.01 1.192l3.712-.003c.604-.046 1.137-.285 1.544-.694.313-.316.504-.646.598-1.022l4.557-17.451c.143-.718-.039-1.476-.518-2.066m-33.435-24.765c0 1.335-.521 2.591-1.465 3.535s-2.2 1.465-3.535 1.465-2.591-.521-3.535-1.465-1.465-2.2-1.465-3.535.521-2.591 1.465-3.535 2.2-1.465 3.535-1.465 2.591.521 3.535 1.465 1.465 2.2 1.465 3.535"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
4
app/views/shared/icons/_i2p_step_9.svg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 76 76" enable-background="new 0 0 76 76">
|
||||||
|
<path d="m68 67c-1.725 0-3.36.541-4.723 1.545-2.298-4.02-6.592-6.545-11.277-6.545-2.734 0-5.359.853-7.555 2.43l-2.286-15.43h1.228l3.829 7.645c.339.598.962.979 1.724 1.022l2.812-.003c.507-.039.974-.25 1.316-.595.264-.266.433-.559.514-.882l3.433-13.145c.12-.611-.037-1.258-.449-1.763l-7.385-8.268c.231-2.875.354-5.376.374-7.641-.023-10.507-2.871-17.462-10.162-24.806-.737-.742-2.072-.715-2.829.044-5.617 5.659-8.309 10.336-9.446 16.463-1.267.186-2.438.764-3.36 1.686-1.134 1.134-1.758 2.64-1.758 4.243s.624 3.109 1.758 4.242c1.133 1.134 2.639 1.758 4.242 1.758s3.109-.624 4.242-1.758c1.134-1.133 1.758-2.639 1.758-4.242s-.624-3.109-1.758-4.242c-.858-.859-1.932-1.424-3.098-1.648 1.095-5.538 3.637-9.855 8.83-15.14 6.874 6.924 9.561 13.485 9.581 23.392-.021 2.316-.151 4.903-.402 7.91-.023.273.067.544.25.749l7.663 8.572-3.391 13.07-2.695.036-4.081-8.15c-.17-.339-.516-.553-.895-.553h-12.01c-.379 0-.725.214-.895.553l-4.04 8.114-2.707.015-3.427-13.07 7.671-8.588c.367-.412.332-1.044-.08-1.412-.411-.366-1.043-.333-1.412.08l-7.7 8.623c-.383.47-.54 1.116-.406 1.787l3.419 13.08c.216.829.98 1.438 1.907 1.48h2.735c.508 0 1.016-.218 1.391-.595.091-.09.242-.241.358-.475l3.804-7.597h1.228l-2.286 15.43c-2.196-1.577-4.821-2.43-7.555-2.43-4.685 0-8.979 2.53-11.277 6.545-1.363-1-2.998-1.545-4.723-1.545-4.411 0-8 3.589-8 8 0 .553.447 1 1 1h74c.553 0 1-.447 1-1 0-4.411-3.589-8-8-8m-36-44c0 1.068-.416 2.072-1.172 2.828-1.512 1.512-4.145 1.512-5.656 0-.756-.756-1.172-1.76-1.172-2.828s.416-2.072 1.172-2.828 1.76-1.172 2.828-1.172 2.072.416 2.828 1.172 1.172 1.76 1.172 2.828m-29.917 51c.478-2.834 2.949-5 5.917-5 1.638 0 3.17.652 4.313 1.836.231.24.562.35.895.29.327-.058.604-.274.739-.579 1.765-3.977 5.711-6.547 10.05-6.547 2.836 0 5.532 1.085 7.593 3.055.271.258.665.345 1.016.224.354-.122.61-.43.665-.8l2.588-17.479h4.275l2.589 17.479c.055.37.312.678.665.8s.745.035 1.016-.224c2.061-1.97 4.757-3.055 7.593-3.055 4.343 0 8.288 2.57 10.05 6.547.135.305.412.521.739.579.329.059.663-.051.895-.29 1.143-1.184 2.675-1.836 4.313-1.836 2.968 0 5.439 2.166 5.917 5h-71.834"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
|
@ -100,7 +100,7 @@
|
||||||
Snippets
|
Snippets
|
||||||
|
|
||||||
%div{ class: container_class }
|
%div{ class: container_class }
|
||||||
- if @user == current_user && show_user_callout?
|
- if @user == current_user && show_callout?('user_callout_dismissed')
|
||||||
= render 'shared/user_callout'
|
= render 'shared/user_callout'
|
||||||
.tab-content
|
.tab-content
|
||||||
#activity.tab-pane
|
#activity.tab-pane
|
||||||
|
|
|
@ -3,29 +3,17 @@ class GitlabUsagePingWorker
|
||||||
|
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
include CronjobQueue
|
include CronjobQueue
|
||||||
include HTTParty
|
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
return unless current_application_settings.usage_ping_enabled
|
|
||||||
|
|
||||||
# Multiple Sidekiq workers could run this. We should only do this at most once a day.
|
# Multiple Sidekiq workers could run this. We should only do this at most once a day.
|
||||||
return unless try_obtain_lease
|
return unless try_obtain_lease
|
||||||
|
|
||||||
begin
|
SubmitUsagePingService.new.execute
|
||||||
HTTParty.post(url,
|
|
||||||
body: Gitlab::UsageData.to_json(force_refresh: true),
|
|
||||||
headers: { 'Content-type' => 'application/json' }
|
|
||||||
)
|
|
||||||
rescue HTTParty::Error => e
|
|
||||||
Rails.logger.info "Unable to contact GitLab, Inc.: #{e}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
def try_obtain_lease
|
def try_obtain_lease
|
||||||
Gitlab::ExclusiveLease.new('gitlab_usage_ping_worker:ping', timeout: LEASE_TIMEOUT).try_obtain
|
Gitlab::ExclusiveLease.new('gitlab_usage_ping_worker:ping', timeout: LEASE_TIMEOUT).try_obtain
|
||||||
end
|
end
|
||||||
|
|
||||||
def url
|
|
||||||
'https://version.gitlab.com/usage_data'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
4
changelogs/unreleased/30469-convdev-index.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
title: Add ConvDev Index page to admin area
|
||||||
|
merge_request: 11377
|
||||||
|
author:
|
|
@ -72,6 +72,8 @@ namespace :admin do
|
||||||
resource :system_info, controller: 'system_info', only: [:show]
|
resource :system_info, controller: 'system_info', only: [:show]
|
||||||
resources :requests_profiles, only: [:index, :show], param: :name, constraints: { name: /.+\.html/ }
|
resources :requests_profiles, only: [:index, :show], param: :name, constraints: { name: /.+\.html/ }
|
||||||
|
|
||||||
|
get 'conversational_development_index' => 'conversational_development_index#show'
|
||||||
|
|
||||||
resources :projects, only: [:index]
|
resources :projects, only: [:index]
|
||||||
|
|
||||||
scope(path: 'projects/*namespace_id',
|
scope(path: 'projects/*namespace_id',
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
Gitlab::Seeder.quiet do
|
||||||
|
conversational_development_index_metric = ConversationalDevelopmentIndex::Metric.new(
|
||||||
|
leader_issues: 10.2,
|
||||||
|
instance_issues: 3.2,
|
||||||
|
|
||||||
|
leader_notes: 25.3,
|
||||||
|
instance_notes: 23.2,
|
||||||
|
|
||||||
|
leader_milestones: 16.2,
|
||||||
|
instance_milestones: 5.5,
|
||||||
|
|
||||||
|
leader_boards: 5.2,
|
||||||
|
instance_boards: 3.2,
|
||||||
|
|
||||||
|
leader_merge_requests: 5.2,
|
||||||
|
instance_merge_requests: 3.2,
|
||||||
|
|
||||||
|
leader_ci_pipelines: 25.1,
|
||||||
|
instance_ci_pipelines: 21.3,
|
||||||
|
|
||||||
|
leader_environments: 3.3,
|
||||||
|
instance_environments: 2.2,
|
||||||
|
|
||||||
|
leader_deployments: 41.3,
|
||||||
|
instance_deployments: 15.2,
|
||||||
|
|
||||||
|
leader_projects_prometheus_active: 0.31,
|
||||||
|
instance_projects_prometheus_active: 0.30,
|
||||||
|
|
||||||
|
leader_service_desk_issues: 15.8,
|
||||||
|
instance_service_desk_issues: 15.1
|
||||||
|
)
|
||||||
|
|
||||||
|
if conversational_development_index_metric.save
|
||||||
|
print '.'
|
||||||
|
else
|
||||||
|
puts conversational_development_index_metric.errors.full_messages
|
||||||
|
print 'F'
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,39 @@
|
||||||
|
class CreateConversationalDevelopmentIndexMetrics < ActiveRecord::Migration
|
||||||
|
DOWNTIME = false
|
||||||
|
|
||||||
|
def change
|
||||||
|
create_table :conversational_development_index_metrics do |t|
|
||||||
|
t.float :leader_issues, null: false
|
||||||
|
t.float :instance_issues, null: false
|
||||||
|
|
||||||
|
t.float :leader_notes, null: false
|
||||||
|
t.float :instance_notes, null: false
|
||||||
|
|
||||||
|
t.float :leader_milestones, null: false
|
||||||
|
t.float :instance_milestones, null: false
|
||||||
|
|
||||||
|
t.float :leader_boards, null: false
|
||||||
|
t.float :instance_boards, null: false
|
||||||
|
|
||||||
|
t.float :leader_merge_requests, null: false
|
||||||
|
t.float :instance_merge_requests, null: false
|
||||||
|
|
||||||
|
t.float :leader_ci_pipelines, null: false
|
||||||
|
t.float :instance_ci_pipelines, null: false
|
||||||
|
|
||||||
|
t.float :leader_environments, null: false
|
||||||
|
t.float :instance_environments, null: false
|
||||||
|
|
||||||
|
t.float :leader_deployments, null: false
|
||||||
|
t.float :instance_deployments, null: false
|
||||||
|
|
||||||
|
t.float :leader_projects_prometheus_active, null: false
|
||||||
|
t.float :instance_projects_prometheus_active, null: false
|
||||||
|
|
||||||
|
t.float :leader_service_desk_issues, null: false
|
||||||
|
t.float :instance_service_desk_issues, null: false
|
||||||
|
|
||||||
|
t.timestamps null: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
25
db/schema.rb
|
@ -371,6 +371,31 @@ ActiveRecord::Schema.define(version: 20170525174156) do
|
||||||
add_index "container_repositories", ["project_id", "name"], name: "index_container_repositories_on_project_id_and_name", unique: true, using: :btree
|
add_index "container_repositories", ["project_id", "name"], name: "index_container_repositories_on_project_id_and_name", unique: true, using: :btree
|
||||||
add_index "container_repositories", ["project_id"], name: "index_container_repositories_on_project_id", using: :btree
|
add_index "container_repositories", ["project_id"], name: "index_container_repositories_on_project_id", using: :btree
|
||||||
|
|
||||||
|
create_table "conversational_development_index_metrics", force: :cascade do |t|
|
||||||
|
t.float "leader_issues", null: false
|
||||||
|
t.float "instance_issues", null: false
|
||||||
|
t.float "leader_notes", null: false
|
||||||
|
t.float "instance_notes", null: false
|
||||||
|
t.float "leader_milestones", null: false
|
||||||
|
t.float "instance_milestones", null: false
|
||||||
|
t.float "leader_boards", null: false
|
||||||
|
t.float "instance_boards", null: false
|
||||||
|
t.float "leader_merge_requests", null: false
|
||||||
|
t.float "instance_merge_requests", null: false
|
||||||
|
t.float "leader_ci_pipelines", null: false
|
||||||
|
t.float "instance_ci_pipelines", null: false
|
||||||
|
t.float "leader_environments", null: false
|
||||||
|
t.float "instance_environments", null: false
|
||||||
|
t.float "leader_deployments", null: false
|
||||||
|
t.float "instance_deployments", null: false
|
||||||
|
t.float "leader_projects_prometheus_active", null: false
|
||||||
|
t.float "instance_projects_prometheus_active", null: false
|
||||||
|
t.float "leader_service_desk_issues", null: false
|
||||||
|
t.float "instance_service_desk_issues", null: false
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
end
|
||||||
|
|
||||||
create_table "deploy_keys_projects", force: :cascade do |t|
|
create_table "deploy_keys_projects", force: :cascade do |t|
|
||||||
t.integer "deploy_key_id", null: false
|
t.integer "deploy_key_id", null: false
|
||||||
t.integer "project_id", null: false
|
t.integer "project_id", null: false
|
||||||
|
|
33
spec/factories/conversational_development_index_metrics.rb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
FactoryGirl.define do
|
||||||
|
factory :conversational_development_index_metric, class: ConversationalDevelopmentIndex::Metric do
|
||||||
|
leader_issues 9.256
|
||||||
|
instance_issues 1.234
|
||||||
|
|
||||||
|
leader_notes 30.33333
|
||||||
|
instance_notes 28.123
|
||||||
|
|
||||||
|
leader_milestones 16.2456
|
||||||
|
instance_milestones 1.234
|
||||||
|
|
||||||
|
leader_boards 5.2123
|
||||||
|
instance_boards 3.254
|
||||||
|
|
||||||
|
leader_merge_requests 1.2
|
||||||
|
instance_merge_requests 0.6
|
||||||
|
|
||||||
|
leader_ci_pipelines 12.1234
|
||||||
|
instance_ci_pipelines 2.344
|
||||||
|
|
||||||
|
leader_environments 3.3333
|
||||||
|
instance_environments 2.2222
|
||||||
|
|
||||||
|
leader_deployments 1.200
|
||||||
|
instance_deployments 0.771
|
||||||
|
|
||||||
|
leader_projects_prometheus_active 0.111
|
||||||
|
instance_projects_prometheus_active 0.109
|
||||||
|
|
||||||
|
leader_service_desk_issues 15.891
|
||||||
|
instance_service_desk_issues 13.345
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,40 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'Admin Conversational Development Index' do
|
||||||
|
before do
|
||||||
|
login_as :admin
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when usage ping is disabled' do
|
||||||
|
it 'shows empty state' do
|
||||||
|
stub_application_setting(usage_ping_enabled: false)
|
||||||
|
|
||||||
|
visit admin_conversational_development_index_path
|
||||||
|
|
||||||
|
expect(page).to have_content('Usage ping is not enabled')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there is no data to display' do
|
||||||
|
it 'shows empty state' do
|
||||||
|
stub_application_setting(usage_ping_enabled: true)
|
||||||
|
|
||||||
|
visit admin_conversational_development_index_path
|
||||||
|
|
||||||
|
expect(page).to have_content('Data is still calculating')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there is data to display' do
|
||||||
|
it 'shows numbers for each metric' do
|
||||||
|
stub_application_setting(usage_ping_enabled: true)
|
||||||
|
create(:conversational_development_index_metric)
|
||||||
|
|
||||||
|
visit admin_conversational_development_index_path
|
||||||
|
|
||||||
|
expect(page).to have_content(
|
||||||
|
'Issues created per active user 1.2 You 9.3 Lead 13.3%'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,36 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe ConversationalDevelopmentIndex::MetricPresenter do
|
||||||
|
subject { described_class.new(metric) }
|
||||||
|
let(:metric) { build(:conversational_development_index_metric) }
|
||||||
|
|
||||||
|
describe '#cards' do
|
||||||
|
it 'includes instance score, leader score and percentage score' do
|
||||||
|
issues_card = subject.cards.first
|
||||||
|
|
||||||
|
expect(issues_card.instance_score).to eq 1.234
|
||||||
|
expect(issues_card.leader_score).to eq 9.256
|
||||||
|
expect(issues_card.percentage_score).to be_within(0.1).of(13.3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#idea_to_production_steps' do
|
||||||
|
it 'returns percentage score when it depends on a single feature' do
|
||||||
|
code_step = subject.idea_to_production_steps.fourth
|
||||||
|
|
||||||
|
expect(code_step.percentage_score).to be_within(0.1).of(50.0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns percentage score when it depends on two features' do
|
||||||
|
issue_step = subject.idea_to_production_steps.second
|
||||||
|
|
||||||
|
expect(issue_step.percentage_score).to be_within(0.1).of(53.0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#average_percentage_score' do
|
||||||
|
it 'calculates an average value across all the features' do
|
||||||
|
expect(subject.average_percentage_score).to be_within(0.1).of(55.8)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
101
spec/services/submit_usage_ping_service_spec.rb
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe SubmitUsagePingService do
|
||||||
|
context 'when usage ping is disabled' do
|
||||||
|
before do
|
||||||
|
stub_application_setting(usage_ping_enabled: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not run' do
|
||||||
|
expect(HTTParty).not_to receive(:post)
|
||||||
|
|
||||||
|
result = subject.execute
|
||||||
|
|
||||||
|
expect(result).to eq false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when usage ping is enabled' do
|
||||||
|
before do
|
||||||
|
stub_application_setting(usage_ping_enabled: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sends a POST request' do
|
||||||
|
response = stub_response(without_conv_index_params)
|
||||||
|
|
||||||
|
subject.execute
|
||||||
|
|
||||||
|
expect(response).to have_been_requested
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'refreshes usage data statistics before submitting' do
|
||||||
|
stub_response(without_conv_index_params)
|
||||||
|
|
||||||
|
expect(Gitlab::UsageData).to receive(:to_json)
|
||||||
|
.with(force_refresh: true)
|
||||||
|
.and_call_original
|
||||||
|
|
||||||
|
subject.execute
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'saves conversational development index data from the response' do
|
||||||
|
stub_response(with_conv_index_params)
|
||||||
|
|
||||||
|
expect { subject.execute }
|
||||||
|
.to change { ConversationalDevelopmentIndex::Metric.count }
|
||||||
|
.by(1)
|
||||||
|
|
||||||
|
expect(ConversationalDevelopmentIndex::Metric.last.leader_issues).to eq 10.2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def without_conv_index_params
|
||||||
|
{
|
||||||
|
conv_index: {}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def with_conv_index_params
|
||||||
|
{
|
||||||
|
conv_index: {
|
||||||
|
leader_issues: 10.2,
|
||||||
|
instance_issues: 3.2,
|
||||||
|
|
||||||
|
leader_notes: 25.3,
|
||||||
|
instance_notes: 23.2,
|
||||||
|
|
||||||
|
leader_milestones: 16.2,
|
||||||
|
instance_milestones: 5.5,
|
||||||
|
|
||||||
|
leader_boards: 5.2,
|
||||||
|
instance_boards: 3.2,
|
||||||
|
|
||||||
|
leader_merge_requests: 5.2,
|
||||||
|
instance_merge_requests: 3.2,
|
||||||
|
|
||||||
|
leader_ci_pipelines: 25.1,
|
||||||
|
instance_ci_pipelines: 21.3,
|
||||||
|
|
||||||
|
leader_environments: 3.3,
|
||||||
|
instance_environments: 2.2,
|
||||||
|
|
||||||
|
leader_deployments: 41.3,
|
||||||
|
instance_deployments: 15.2,
|
||||||
|
|
||||||
|
leader_projects_prometheus_active: 0.31,
|
||||||
|
instance_projects_prometheus_active: 0.30,
|
||||||
|
|
||||||
|
leader_service_desk_issues: 15.8,
|
||||||
|
instance_service_desk_issues: 15.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def stub_response(body)
|
||||||
|
stub_request(:post, 'https://version.gitlab.com/usage_data').
|
||||||
|
to_return(
|
||||||
|
headers: { 'Content-Type' => 'application/json' },
|
||||||
|
body: body.to_json
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,21 +3,11 @@ require 'spec_helper'
|
||||||
describe GitlabUsagePingWorker do
|
describe GitlabUsagePingWorker do
|
||||||
subject { described_class.new }
|
subject { described_class.new }
|
||||||
|
|
||||||
it "sends POST request" do
|
it 'delegates to SubmitUsagePingService' do
|
||||||
stub_application_setting(usage_ping_enabled: true)
|
allow(subject).to receive(:try_obtain_lease).and_return(true)
|
||||||
|
|
||||||
stub_request(:post, "https://version.gitlab.com/usage_data").
|
expect_any_instance_of(SubmitUsagePingService).to receive(:execute)
|
||||||
to_return(status: 200, body: '', headers: {})
|
|
||||||
expect(Gitlab::UsageData).to receive(:to_json).with({ force_refresh: true }).and_call_original
|
|
||||||
expect(subject).to receive(:try_obtain_lease).and_return(true)
|
|
||||||
|
|
||||||
expect(subject.perform.response.code.to_i).to eq(200)
|
subject.perform
|
||||||
end
|
|
||||||
|
|
||||||
it "does not run if usage ping is disabled" do
|
|
||||||
stub_application_setting(usage_ping_enabled: false)
|
|
||||||
|
|
||||||
expect(subject).not_to receive(:try_obtain_lease)
|
|
||||||
expect(subject).not_to receive(:perform)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|