Merge branch 'invite'
Conflicts: public/css/less/gfbox.less public/emails/reset_password.html public/emails/welcome_on_signup.html
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
@@ -3,6 +3,7 @@ coverage/
|
||||
.aws-config.json
|
||||
awsconfig
|
||||
/dist
|
||||
/emails/dist
|
||||
/tmp
|
||||
|
||||
docs/AWS_S3_BUCKET
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
- npm install
|
||||
- grunt (default task will build new inlines email templates)
|
||||
- grunt watch (will build on source html or css change)
|
||||
|
||||
assembled email templates will be in dist/ and final
|
||||
inlined templates will be in ../public/emails/
|
||||
|
||||
@@ -0,0 +1,688 @@
|
||||
/**********************************************
|
||||
* Ink v1.0.5 - Copyright 2013 ZURB Inc *
|
||||
**********************************************/
|
||||
|
||||
/* Client-specific Styles & Reset */
|
||||
|
||||
#outlook a {
|
||||
padding:0;
|
||||
}
|
||||
|
||||
body{
|
||||
width:100% !important;
|
||||
min-width: 100%;
|
||||
-webkit-text-size-adjust:100%;
|
||||
-ms-text-size-adjust:100%;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.ExternalClass {
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.ExternalClass,
|
||||
.ExternalClass p,
|
||||
.ExternalClass span,
|
||||
.ExternalClass font,
|
||||
.ExternalClass td,
|
||||
.ExternalClass div {
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
#backgroundTable {
|
||||
margin:0;
|
||||
padding:0;
|
||||
width:100% !important;
|
||||
line-height: 100% !important;
|
||||
}
|
||||
|
||||
img {
|
||||
outline:none;
|
||||
text-decoration:none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
float: left;
|
||||
clear: both;
|
||||
display: block;
|
||||
}
|
||||
|
||||
center {
|
||||
width: 100%;
|
||||
min-width: 580px;
|
||||
}
|
||||
|
||||
a img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 0 10px;
|
||||
}
|
||||
|
||||
table {
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
td {
|
||||
word-break: break-word;
|
||||
-webkit-hyphens: auto;
|
||||
-moz-hyphens: auto;
|
||||
hyphens: auto;
|
||||
border-collapse: collapse !important;
|
||||
}
|
||||
|
||||
table, tr, td {
|
||||
padding: 0;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
hr {
|
||||
color: #d9d9d9;
|
||||
background-color: #d9d9d9;
|
||||
height: 1px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Responsive Grid */
|
||||
|
||||
table.body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table.container {
|
||||
width: 580px;
|
||||
margin: 0 auto;
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
table.row {
|
||||
padding: 0px;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
table.container table.row {
|
||||
display: block;
|
||||
}
|
||||
|
||||
td.wrapper {
|
||||
padding: 10px 20px 0px 0px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
table.columns,
|
||||
table.column {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
table.columns td,
|
||||
table.column td {
|
||||
padding: 0px 0px 10px;
|
||||
}
|
||||
|
||||
table.columns td.sub-columns,
|
||||
table.column td.sub-columns,
|
||||
table.columns td.sub-column,
|
||||
table.column td.sub-column {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
td.sub-column, td.sub-columns {
|
||||
min-width: 0px;
|
||||
}
|
||||
|
||||
table.row td.last,
|
||||
table.container td.last {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
table.one { width: 30px; }
|
||||
table.two { width: 80px; }
|
||||
table.three { width: 130px; }
|
||||
table.four { width: 180px; }
|
||||
table.five { width: 230px; }
|
||||
table.six { width: 280px; }
|
||||
table.seven { width: 330px; }
|
||||
table.eight { width: 380px; }
|
||||
table.nine { width: 430px; }
|
||||
table.ten { width: 480px; }
|
||||
table.eleven { width: 530px; }
|
||||
table.twelve { width: 580px; }
|
||||
|
||||
table.one center { min-width: 30px; }
|
||||
table.two center { min-width: 80px; }
|
||||
table.three center { min-width: 130px; }
|
||||
table.four center { min-width: 180px; }
|
||||
table.five center { min-width: 230px; }
|
||||
table.six center { min-width: 280px; }
|
||||
table.seven center { min-width: 330px; }
|
||||
table.eight center { min-width: 380px; }
|
||||
table.nine center { min-width: 430px; }
|
||||
table.ten center { min-width: 480px; }
|
||||
table.eleven center { min-width: 530px; }
|
||||
table.twelve center { min-width: 580px; }
|
||||
|
||||
table.one .panel center { min-width: 10px; }
|
||||
table.two .panel center { min-width: 60px; }
|
||||
table.three .panel center { min-width: 110px; }
|
||||
table.four .panel center { min-width: 160px; }
|
||||
table.five .panel center { min-width: 210px; }
|
||||
table.six .panel center { min-width: 260px; }
|
||||
table.seven .panel center { min-width: 310px; }
|
||||
table.eight .panel center { min-width: 360px; }
|
||||
table.nine .panel center { min-width: 410px; }
|
||||
table.ten .panel center { min-width: 460px; }
|
||||
table.eleven .panel center { min-width: 510px; }
|
||||
table.twelve .panel center { min-width: 560px; }
|
||||
|
||||
.body .columns td.one,
|
||||
.body .column td.one { width: 8.333333%; }
|
||||
.body .columns td.two,
|
||||
.body .column td.two { width: 16.666666%; }
|
||||
.body .columns td.three,
|
||||
.body .column td.three { width: 25%; }
|
||||
.body .columns td.four,
|
||||
.body .column td.four { width: 33.333333%; }
|
||||
.body .columns td.five,
|
||||
.body .column td.five { width: 41.666666%; }
|
||||
.body .columns td.six,
|
||||
.body .column td.six { width: 50%; }
|
||||
.body .columns td.seven,
|
||||
.body .column td.seven { width: 58.333333%; }
|
||||
.body .columns td.eight,
|
||||
.body .column td.eight { width: 66.666666%; }
|
||||
.body .columns td.nine,
|
||||
.body .column td.nine { width: 75%; }
|
||||
.body .columns td.ten,
|
||||
.body .column td.ten { width: 83.333333%; }
|
||||
.body .columns td.eleven,
|
||||
.body .column td.eleven { width: 91.666666%; }
|
||||
.body .columns td.twelve,
|
||||
.body .column td.twelve { width: 100%; }
|
||||
|
||||
td.offset-by-one { padding-left: 50px; }
|
||||
td.offset-by-two { padding-left: 100px; }
|
||||
td.offset-by-three { padding-left: 150px; }
|
||||
td.offset-by-four { padding-left: 200px; }
|
||||
td.offset-by-five { padding-left: 250px; }
|
||||
td.offset-by-six { padding-left: 300px; }
|
||||
td.offset-by-seven { padding-left: 350px; }
|
||||
td.offset-by-eight { padding-left: 400px; }
|
||||
td.offset-by-nine { padding-left: 450px; }
|
||||
td.offset-by-ten { padding-left: 500px; }
|
||||
td.offset-by-eleven { padding-left: 550px; }
|
||||
|
||||
td.expander {
|
||||
visibility: hidden;
|
||||
width: 0px;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
table.columns .text-pad,
|
||||
table.column .text-pad {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
table.columns .left-text-pad,
|
||||
table.columns .text-pad-left,
|
||||
table.column .left-text-pad,
|
||||
table.column .text-pad-left {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
table.columns .right-text-pad,
|
||||
table.columns .text-pad-right,
|
||||
table.column .right-text-pad,
|
||||
table.column .text-pad-right {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
/* Block Grid */
|
||||
|
||||
.block-grid {
|
||||
width: 100%;
|
||||
max-width: 580px;
|
||||
}
|
||||
|
||||
.block-grid td {
|
||||
display: inline-block;
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
.two-up td {
|
||||
width:270px;
|
||||
}
|
||||
|
||||
.three-up td {
|
||||
width:173px;
|
||||
}
|
||||
|
||||
.four-up td {
|
||||
width:125px;
|
||||
}
|
||||
|
||||
.five-up td {
|
||||
width:96px;
|
||||
}
|
||||
|
||||
.six-up td {
|
||||
width:76px;
|
||||
}
|
||||
|
||||
.seven-up td {
|
||||
width:62px;
|
||||
}
|
||||
|
||||
.eight-up td {
|
||||
width:52px;
|
||||
}
|
||||
|
||||
/* Alignment & Visibility Classes */
|
||||
|
||||
table.center, td.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1.center,
|
||||
h2.center,
|
||||
h3.center,
|
||||
h4.center,
|
||||
h5.center,
|
||||
h6.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
span.center {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
img.center {
|
||||
margin: 0 auto;
|
||||
float: none;
|
||||
}
|
||||
|
||||
.show-for-small,
|
||||
.hide-for-desktop {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Typography */
|
||||
|
||||
body, table.body, h1, h2, h3, h4, h5, h6, p, td {
|
||||
color: #222222;
|
||||
font-family: "Helvetica", "Arial", sans-serif;
|
||||
font-weight: normal;
|
||||
padding:0;
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
h1 {font-size: 40px;}
|
||||
h2 {font-size: 36px;}
|
||||
h3 {font-size: 32px;}
|
||||
h4 {font-size: 28px;}
|
||||
h5 {font-size: 24px;}
|
||||
h6 {font-size: 20px;}
|
||||
body, table.body, p, td {font-size: 14px;line-height:19px;}
|
||||
|
||||
p.lead, p.lede, p.leed {
|
||||
font-size: 18px;
|
||||
line-height:21px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #2ba6cb;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #2795b6 !important;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: #2795b6 !important;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #2ba6cb !important;
|
||||
}
|
||||
|
||||
h1 a,
|
||||
h2 a,
|
||||
h3 a,
|
||||
h4 a,
|
||||
h5 a,
|
||||
h6 a {
|
||||
color: #2ba6cb;
|
||||
}
|
||||
|
||||
h1 a:active,
|
||||
h2 a:active,
|
||||
h3 a:active,
|
||||
h4 a:active,
|
||||
h5 a:active,
|
||||
h6 a:active {
|
||||
color: #2ba6cb !important;
|
||||
}
|
||||
|
||||
h1 a:visited,
|
||||
h2 a:visited,
|
||||
h3 a:visited,
|
||||
h4 a:visited,
|
||||
h5 a:visited,
|
||||
h6 a:visited {
|
||||
color: #2ba6cb !important;
|
||||
}
|
||||
|
||||
/* Panels */
|
||||
|
||||
.panel {
|
||||
background: #f2f2f2;
|
||||
border: 1px solid #d9d9d9;
|
||||
padding: 10px !important;
|
||||
}
|
||||
|
||||
.sub-grid table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sub-grid td.sub-columns {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
|
||||
table.button,
|
||||
table.tiny-button,
|
||||
table.small-button,
|
||||
table.medium-button,
|
||||
table.large-button {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
table.button td,
|
||||
table.tiny-button td,
|
||||
table.small-button td,
|
||||
table.medium-button td,
|
||||
table.large-button td {
|
||||
display: block;
|
||||
width: auto !important;
|
||||
text-align: center;
|
||||
background: #2ba6cb;
|
||||
border: 1px solid #2284a1;
|
||||
color: #ffffff;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
table.tiny-button td {
|
||||
padding: 5px 0 4px;
|
||||
}
|
||||
|
||||
table.small-button td {
|
||||
padding: 8px 0 7px;
|
||||
}
|
||||
|
||||
table.medium-button td {
|
||||
padding: 12px 0 10px;
|
||||
}
|
||||
|
||||
table.large-button td {
|
||||
padding: 21px 0 18px;
|
||||
}
|
||||
|
||||
table.button td a,
|
||||
table.tiny-button td a,
|
||||
table.small-button td a,
|
||||
table.medium-button td a,
|
||||
table.large-button td a {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
color: #ffffff;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
table.tiny-button td a {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
table.small-button td a {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
table.medium-button td a {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
table.large-button td a {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
table.button:hover td,
|
||||
table.button:visited td,
|
||||
table.button:active td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
|
||||
table.button:hover td a,
|
||||
table.button:visited td a,
|
||||
table.button:active td a {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
table.button:hover td,
|
||||
table.tiny-button:hover td,
|
||||
table.small-button:hover td,
|
||||
table.medium-button:hover td,
|
||||
table.large-button:hover td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
|
||||
table.button:hover td a,
|
||||
table.button:active td a,
|
||||
table.button td a:visited,
|
||||
table.tiny-button:hover td a,
|
||||
table.tiny-button:active td a,
|
||||
table.tiny-button td a:visited,
|
||||
table.small-button:hover td a,
|
||||
table.small-button:active td a,
|
||||
table.small-button td a:visited,
|
||||
table.medium-button:hover td a,
|
||||
table.medium-button:active td a,
|
||||
table.medium-button td a:visited,
|
||||
table.large-button:hover td a,
|
||||
table.large-button:active td a,
|
||||
table.large-button td a:visited {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
table.secondary td {
|
||||
background: #e9e9e9;
|
||||
border-color: #d0d0d0;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
table.secondary td a {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
table.secondary:hover td {
|
||||
background: #d0d0d0 !important;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
table.secondary:hover td a,
|
||||
table.secondary td a:visited,
|
||||
table.secondary:active td a {
|
||||
color: #555 !important;
|
||||
}
|
||||
|
||||
table.success td {
|
||||
background: #5da423;
|
||||
border-color: #457a1a;
|
||||
}
|
||||
|
||||
table.success:hover td {
|
||||
background: #457a1a !important;
|
||||
}
|
||||
|
||||
table.alert td {
|
||||
background: #c60f13;
|
||||
border-color: #970b0e;
|
||||
}
|
||||
|
||||
table.alert:hover td {
|
||||
background: #970b0e !important;
|
||||
}
|
||||
|
||||
table.radius td {
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
table.round td {
|
||||
-webkit-border-radius: 500px;
|
||||
-moz-border-radius: 500px;
|
||||
border-radius: 500px;
|
||||
}
|
||||
|
||||
/* Outlook First */
|
||||
|
||||
body.outlook p {
|
||||
display: inline !important;
|
||||
}
|
||||
|
||||
/* Media Queries */
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
|
||||
table[class="body"] img {
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
table[class="body"] center {
|
||||
min-width: 0 !important;
|
||||
}
|
||||
|
||||
table[class="body"] .container {
|
||||
width: 95% !important;
|
||||
}
|
||||
|
||||
table[class="body"] .row {
|
||||
width: 100% !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
table[class="body"] .wrapper {
|
||||
display: block !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
table[class="body"] .columns,
|
||||
table[class="body"] .column {
|
||||
table-layout: fixed !important;
|
||||
float: none !important;
|
||||
width: 100% !important;
|
||||
padding-right: 0px !important;
|
||||
padding-left: 0px !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
table[class="body"] .wrapper.first .columns,
|
||||
table[class="body"] .wrapper.first .column {
|
||||
display: table !important;
|
||||
}
|
||||
|
||||
table[class="body"] table.columns td,
|
||||
table[class="body"] table.column td {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
table[class="body"] .columns td.one,
|
||||
table[class="body"] .column td.one { width: 8.333333% !important; }
|
||||
table[class="body"] .columns td.two,
|
||||
table[class="body"] .column td.two { width: 16.666666% !important; }
|
||||
table[class="body"] .columns td.three,
|
||||
table[class="body"] .column td.three { width: 25% !important; }
|
||||
table[class="body"] .columns td.four,
|
||||
table[class="body"] .column td.four { width: 33.333333% !important; }
|
||||
table[class="body"] .columns td.five,
|
||||
table[class="body"] .column td.five { width: 41.666666% !important; }
|
||||
table[class="body"] .columns td.six,
|
||||
table[class="body"] .column td.six { width: 50% !important; }
|
||||
table[class="body"] .columns td.seven,
|
||||
table[class="body"] .column td.seven { width: 58.333333% !important; }
|
||||
table[class="body"] .columns td.eight,
|
||||
table[class="body"] .column td.eight { width: 66.666666% !important; }
|
||||
table[class="body"] .columns td.nine,
|
||||
table[class="body"] .column td.nine { width: 75% !important; }
|
||||
table[class="body"] .columns td.ten,
|
||||
table[class="body"] .column td.ten { width: 83.333333% !important; }
|
||||
table[class="body"] .columns td.eleven,
|
||||
table[class="body"] .column td.eleven { width: 91.666666% !important; }
|
||||
table[class="body"] .columns td.twelve,
|
||||
table[class="body"] .column td.twelve { width: 100% !important; }
|
||||
|
||||
table[class="body"] td.offset-by-one,
|
||||
table[class="body"] td.offset-by-two,
|
||||
table[class="body"] td.offset-by-three,
|
||||
table[class="body"] td.offset-by-four,
|
||||
table[class="body"] td.offset-by-five,
|
||||
table[class="body"] td.offset-by-six,
|
||||
table[class="body"] td.offset-by-seven,
|
||||
table[class="body"] td.offset-by-eight,
|
||||
table[class="body"] td.offset-by-nine,
|
||||
table[class="body"] td.offset-by-ten,
|
||||
table[class="body"] td.offset-by-eleven {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
table[class="body"] table.columns td.expander {
|
||||
width: 1px !important;
|
||||
}
|
||||
|
||||
table[class="body"] .right-text-pad,
|
||||
table[class="body"] .text-pad-right {
|
||||
padding-left: 10px !important;
|
||||
}
|
||||
|
||||
table[class="body"] .left-text-pad,
|
||||
table[class="body"] .text-pad-left {
|
||||
padding-right: 10px !important;
|
||||
}
|
||||
|
||||
table[class="body"] .hide-for-small,
|
||||
table[class="body"] .show-for-desktop {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
table[class="body"] .show-for-small,
|
||||
table[class="body"] .hide-for-desktop {
|
||||
display: inherit !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
|
||||
body, table.body, h1, h2, h3, h4, h5, h6, p, td {
|
||||
font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-webkit-text-size-adjust: none;
|
||||
}
|
||||
|
||||
table.facebook td {
|
||||
background: #3b5998;
|
||||
border-color: #2d4473;
|
||||
}
|
||||
|
||||
table.facebook:hover td {
|
||||
background: #2d4473 !important;
|
||||
}
|
||||
|
||||
table.twitter td {
|
||||
background: #00acee;
|
||||
border-color: #0087bb;
|
||||
}
|
||||
|
||||
table.twitter:hover td {
|
||||
background: #0087bb !important;
|
||||
}
|
||||
|
||||
table.google-plus td {
|
||||
background-color: #DB4A39;
|
||||
border-color: #CC0000;
|
||||
}
|
||||
|
||||
table.google-plus:hover td {
|
||||
background: #CC0000 !important;
|
||||
}
|
||||
|
||||
.template-label {
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.callout .wrapper {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.callout .panel {
|
||||
background: #ECF8FF;
|
||||
border-color: #b9e5ff;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: #333;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
table[class="body"] .right-text-pad {
|
||||
padding-left: 10px !important;
|
||||
}
|
||||
|
||||
table[class="body"] .left-text-pad {
|
||||
padding-right: 10px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
default:
|
||||
- 'clean'
|
||||
- 'assemble'
|
||||
- 'replace'
|
||||
- 'uncss'
|
||||
- 'processhtml'
|
||||
- 'premailer'
|
||||
@@ -0,0 +1,16 @@
|
||||
module.exports = function() {
|
||||
'use strict';
|
||||
return {
|
||||
options: {
|
||||
layout: 'templates/layouts/default.html',
|
||||
partials: ['templates/partials/*.hbs'],
|
||||
helpers: ['templates/helpers/**/*.js'],
|
||||
data: [],
|
||||
flatten: true
|
||||
},
|
||||
pages: {
|
||||
src: ['templates/*.html'],
|
||||
dest: 'dist/'
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
module.exports = function(config) {
|
||||
return {
|
||||
dist: ['dist'],
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
main: {
|
||||
options: {
|
||||
verbose: true,
|
||||
removeComments: true
|
||||
},
|
||||
files: [{
|
||||
expand: true, // Enable dynamic expansion.
|
||||
cwd: 'dist', // Src matches are relative to this path.
|
||||
src: ['*.html'], // Actual pattern(s) to match.
|
||||
dest: '../public/emails/', // Destination path prefix.
|
||||
}],
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
module.exports = {
|
||||
dist: {
|
||||
files: [{
|
||||
expand: true, // Enable dynamic expansion.
|
||||
cwd: 'dist', // Src matches are relative to this path.
|
||||
src: ['*.html'], // Actual pattern(s) to match.
|
||||
dest: 'dist/', // Destination path prefix.
|
||||
}],
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
module.exports = {
|
||||
dist: {
|
||||
overwrite: true,
|
||||
src: ['dist/*.html'],
|
||||
replacements: [{
|
||||
from: '[[',
|
||||
to: '{{'
|
||||
}, {
|
||||
from: ']]',
|
||||
to: '}}'
|
||||
}]
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
dist: {
|
||||
src: ['dist/*.html'],
|
||||
dest: 'dist/css/tidy.css',
|
||||
options: {
|
||||
report: 'min' // optional: include to report savings
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
module.exports = {
|
||||
src: {
|
||||
files: [
|
||||
//what are the files that we want to watch
|
||||
'assets/css/*.css',
|
||||
'templates/**/*.html',
|
||||
'grunt/*.js',
|
||||
],
|
||||
tasks: ['default'],
|
||||
options: {
|
||||
nospawn: true,
|
||||
livereload: true,
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
module.exports = function(grunt) {
|
||||
|
||||
// load grunt config
|
||||
require('load-grunt-config')(grunt);
|
||||
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Grafana-Email-Campaign",
|
||||
"version": "1.0.0",
|
||||
"description": "Grafana Email templates based on Zurb Ink",
|
||||
"repository": "dnnsldr/",
|
||||
"author": {
|
||||
"name": "dnnsldr",
|
||||
"email": "delder@riester.com",
|
||||
"url": "https://github.com/dnnsldr"
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt": "^0.4.5",
|
||||
"grunt-premailer": "^0.2.10",
|
||||
"grunt-processhtml": "^0.3.3",
|
||||
"grunt-uncss": "^0.3.7",
|
||||
"load-grunt-config": "^0.14.0",
|
||||
"grunt-contrib-watch": "^0.6.1",
|
||||
"grunt-text-replace": "^0.3.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"grunt-assemble": "^0.4.0",
|
||||
"grunt-contrib-clean": "^0.6.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<!-- This email is sent when an existing user is added to an organization -->
|
||||
|
||||
[[Subject .Subject "[[.InvitedBy]] has added you to the Grafana organization [[.OrgName]]"]]
|
||||
|
||||
<table class="row">
|
||||
<tr>
|
||||
<td class="wrapper last">
|
||||
|
||||
<table class="twelve columns">
|
||||
<tr>
|
||||
<td>
|
||||
<h3>You have been added to the Grafana organization [[.OrgName]]</h3>
|
||||
</td>
|
||||
<td class="expander"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="row">
|
||||
<tr>
|
||||
<td class="wrapper last">
|
||||
<table class="twelve columns">
|
||||
<tr>
|
||||
<td class="center">
|
||||
<p>You can switch organization in the left side menu, in the dropdown below your username.</p>
|
||||
</td>
|
||||
<td class="expander"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width"/>
|
||||
<!-- build:css css/tidy.css -->
|
||||
<link inline rel="stylesheet" href="../assets/css/ink.css">
|
||||
<link inline rel="stylesheet" href="../assets/css/style.css">
|
||||
<!-- /build -->
|
||||
</head>
|
||||
<body>
|
||||
<table class="body">
|
||||
<tr>
|
||||
<td class="center" align="center" valign="top">
|
||||
<center>
|
||||
|
||||
<table class="row header">
|
||||
<tr>
|
||||
<td class="center" align="center">
|
||||
<center>
|
||||
|
||||
<table class="container">
|
||||
<tr>
|
||||
<td class="wrapper last">
|
||||
|
||||
<table class="twelve columns">
|
||||
<tr>
|
||||
<td class="six sub-columns center">
|
||||
<img src="http://docs.grafana.org/img/logo_transparent_200x75.png" style="width: 150px; float: none; display: inline">
|
||||
</td>
|
||||
<td class="expander"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="container">
|
||||
<tr>
|
||||
<td>
|
||||
{{> body }}
|
||||
<!-- footer -->
|
||||
<table class="row footer">
|
||||
<tr>
|
||||
<td class="wrapper last">
|
||||
<table class="twelve columns">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<center>
|
||||
<p style="text-align:center;">
|
||||
Sent by <a href="[[.AppUrl]]">Grafana v[[.BuildVersion]]</a>
|
||||
</p>
|
||||
</center>
|
||||
</td>
|
||||
<td class="expander"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- container end below -->
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,44 @@
|
||||
<!-- This email is sent when user who does not already exist in Grafana is added to an organization -->
|
||||
|
||||
[[Subject .Subject "[[.InvitedBy]] has invited you to join Grafana"]]
|
||||
|
||||
<table class="row">
|
||||
<tr>
|
||||
<td class="wrapper last">
|
||||
|
||||
<table class="twelve columns">
|
||||
<tr>
|
||||
<td>
|
||||
<h3>You're invited to sign up to Grafana and join organization [[.OrgName]]</h3>
|
||||
</td>
|
||||
<td class="expander"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="row">
|
||||
<tr>
|
||||
<td class="wrapper last">
|
||||
<table class="twelve columns">
|
||||
<tr>
|
||||
<td class="center">
|
||||
<table class="button radius">
|
||||
<tr>
|
||||
<td>
|
||||
<a href="[[.LinkUrl]]">Complete Sign Up</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td class="expander"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
[[Subject .Subject "Reset your Grafana password - [[.Name]]"]]
|
||||
|
||||
<table class="row">
|
||||
<tr>
|
||||
<td class="wrapper last">
|
||||
|
||||
<table class="twelve columns">
|
||||
<tr>
|
||||
<td>
|
||||
<h3>Hi [[.Name]]</h3>
|
||||
</td>
|
||||
<td class="expander"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="row">
|
||||
<tr>
|
||||
<td class="wrapper last">
|
||||
<table class="twelve columns">
|
||||
<tr>
|
||||
<td class="center">
|
||||
<p>
|
||||
Please click the following link to reset your password within <strong>[[.EmailCodeValidHours]] hours</strong>.
|
||||
</p>
|
||||
<p>
|
||||
<a href="[[.AppUrl]]user/password/reset?code=[[.Code]]">[[.AppUrl]]user/password/reset?code=[[.Code]]</a>
|
||||
</p>
|
||||
<p>Not working? Try copying and pasting it to your browser.</p>
|
||||
</td>
|
||||
<td class="expander"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
[[Subject .Subject "Welcome to Grafana"]]
|
||||
|
||||
<table class="row">
|
||||
<tr>
|
||||
<td class="wrapper last">
|
||||
|
||||
<table class="twelve columns">
|
||||
<tr>
|
||||
<td>
|
||||
<h3>Hi [[.Name]]</h3>
|
||||
</td>
|
||||
<td class="expander"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="row">
|
||||
<tr>
|
||||
<td class="wrapper last">
|
||||
<table class="twelve columns">
|
||||
<tr>
|
||||
<td class="center">
|
||||
<p>
|
||||
If you are new to Grafana please read the <a href="http://docs.grafana.org/guides/gettingstarted/">Getting Started</a> guide.
|
||||
</p>
|
||||
</td>
|
||||
<td class="expander"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ func Register(r *macaron.Macaron) {
|
||||
r.Post("/login", bind(dtos.LoginCommand{}), wrap(LoginPost))
|
||||
r.Get("/login/:name", OAuthLogin)
|
||||
r.Get("/login", LoginView)
|
||||
r.Get("/invite/:code", Index)
|
||||
|
||||
// authed views
|
||||
r.Get("/profile/", reqSignedIn, Index)
|
||||
@@ -42,6 +43,10 @@ func Register(r *macaron.Macaron) {
|
||||
r.Get("/signup", Index)
|
||||
r.Post("/api/user/signup", bind(m.CreateUserCommand{}), wrap(SignUp))
|
||||
|
||||
// invited
|
||||
r.Get("/api/user/invite/:code", wrap(GetInviteInfoByCode))
|
||||
r.Post("/api/user/invite/complete", bind(dtos.CompleteInviteForm{}), wrap(CompleteInvite))
|
||||
|
||||
// reset password
|
||||
r.Get("/user/password/send-reset-email", Index)
|
||||
r.Get("/user/password/reset", Index)
|
||||
@@ -89,6 +94,11 @@ func Register(r *macaron.Macaron) {
|
||||
r.Get("/users", wrap(GetOrgUsersForCurrentOrg))
|
||||
r.Patch("/users/:userId", bind(m.UpdateOrgUserCommand{}), wrap(UpdateOrgUserForCurrentOrg))
|
||||
r.Delete("/users/:userId", wrap(RemoveOrgUserForCurrentOrg))
|
||||
|
||||
// invites
|
||||
r.Get("/invites", wrap(GetPendingOrgInvites))
|
||||
r.Post("/invites", bind(dtos.AddInviteForm{}), wrap(AddOrgInvite))
|
||||
r.Patch("/invites/:code/revoke", wrap(RevokeInvite))
|
||||
}, regOrgAdmin)
|
||||
|
||||
// create new org
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package dtos
|
||||
|
||||
import m "github.com/grafana/grafana/pkg/models"
|
||||
|
||||
type AddInviteForm struct {
|
||||
LoginOrEmail string `json:"loginOrEmail" binding:"Required"`
|
||||
Name string `json:"name"`
|
||||
Role m.RoleType `json:"role" binding:"Required"`
|
||||
SkipEmails bool `json:"skipEmails"`
|
||||
}
|
||||
|
||||
type InviteInfo struct {
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
InvitedBy string `json:"invitedBy"`
|
||||
}
|
||||
|
||||
type CompleteInviteForm struct {
|
||||
InviteCode string `json:"inviteCode"`
|
||||
Email string `json:"email" binding:"Required"`
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
ConfirmPassword string `json:"confirmPassword"`
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/events"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
func GetPendingOrgInvites(c *middleware.Context) Response {
|
||||
query := m.GetTempUsersForOrgQuery{OrgId: c.OrgId, Status: m.TmpUserInvitePending}
|
||||
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
return ApiError(500, "Failed to get invites from db", err)
|
||||
}
|
||||
|
||||
for _, invite := range query.Result {
|
||||
invite.Url = setting.ToAbsUrl("invite/" + invite.Code)
|
||||
}
|
||||
|
||||
return Json(200, query.Result)
|
||||
}
|
||||
|
||||
func AddOrgInvite(c *middleware.Context, inviteDto dtos.AddInviteForm) Response {
|
||||
if !inviteDto.Role.IsValid() {
|
||||
return ApiError(400, "Invalid role specified", nil)
|
||||
}
|
||||
|
||||
// first try get existing user
|
||||
userQuery := m.GetUserByLoginQuery{LoginOrEmail: inviteDto.LoginOrEmail}
|
||||
if err := bus.Dispatch(&userQuery); err != nil {
|
||||
if err != m.ErrUserNotFound {
|
||||
return ApiError(500, "Failed to query db for existing user check", err)
|
||||
}
|
||||
} else {
|
||||
return inviteExistingUserToOrg(c, userQuery.Result, &inviteDto)
|
||||
}
|
||||
|
||||
cmd := m.CreateTempUserCommand{}
|
||||
cmd.OrgId = c.OrgId
|
||||
cmd.Email = inviteDto.LoginOrEmail
|
||||
cmd.Name = inviteDto.Name
|
||||
cmd.Status = m.TmpUserInvitePending
|
||||
cmd.InvitedByUserId = c.UserId
|
||||
cmd.Code = util.GetRandomString(30)
|
||||
cmd.Role = inviteDto.Role
|
||||
cmd.RemoteAddr = c.Req.RemoteAddr
|
||||
|
||||
if err := bus.Dispatch(&cmd); err != nil {
|
||||
return ApiError(500, "Failed to save invite to database", err)
|
||||
}
|
||||
|
||||
// send invite email
|
||||
if !inviteDto.SkipEmails && util.IsEmail(inviteDto.LoginOrEmail) {
|
||||
emailCmd := m.SendEmailCommand{
|
||||
To: []string{inviteDto.LoginOrEmail},
|
||||
Template: "new_user_invite.html",
|
||||
Data: map[string]interface{}{
|
||||
"Name": util.StringsFallback2(cmd.Name, cmd.Email),
|
||||
"OrgName": c.OrgName,
|
||||
"Email": c.Email,
|
||||
"LinkUrl": setting.ToAbsUrl("invite/" + cmd.Code),
|
||||
"InvitedBy": util.StringsFallback3(c.Name, c.Email, c.Login),
|
||||
},
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(&emailCmd); err != nil {
|
||||
return ApiError(500, "Failed to send email invite", err)
|
||||
}
|
||||
|
||||
return ApiSuccess(fmt.Sprintf("Sent invite to %s", inviteDto.LoginOrEmail))
|
||||
}
|
||||
|
||||
return ApiSuccess(fmt.Sprintf("Created invite for %s", inviteDto.LoginOrEmail))
|
||||
}
|
||||
|
||||
func inviteExistingUserToOrg(c *middleware.Context, user *m.User, inviteDto *dtos.AddInviteForm) Response {
|
||||
// user exists, add org role
|
||||
createOrgUserCmd := m.AddOrgUserCommand{OrgId: c.OrgId, UserId: user.Id, Role: inviteDto.Role}
|
||||
if err := bus.Dispatch(&createOrgUserCmd); err != nil {
|
||||
if err == m.ErrOrgUserAlreadyAdded {
|
||||
return ApiError(412, fmt.Sprintf("User %s is already added to organization", inviteDto.LoginOrEmail), err)
|
||||
}
|
||||
return ApiError(500, "Error while trying to create org user", err)
|
||||
} else {
|
||||
|
||||
if !inviteDto.SkipEmails && util.IsEmail(user.Email) {
|
||||
emailCmd := m.SendEmailCommand{
|
||||
To: []string{user.Email},
|
||||
Template: "invited_to_org.html",
|
||||
Data: map[string]interface{}{
|
||||
"Name": user.NameOrFallback(),
|
||||
"OrgName": c.OrgName,
|
||||
"InvitedBy": util.StringsFallback3(c.Name, c.Email, c.Login),
|
||||
},
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(&emailCmd); err != nil {
|
||||
return ApiError(500, "Failed to send email invited_to_org", err)
|
||||
}
|
||||
}
|
||||
|
||||
return ApiSuccess(fmt.Sprintf("Existing Grafana user %s added to org %s", user.NameOrFallback(), c.OrgName))
|
||||
}
|
||||
}
|
||||
|
||||
func RevokeInvite(c *middleware.Context) Response {
|
||||
cmd := m.UpdateTempUserStatusCommand{
|
||||
Code: c.Params(":code"),
|
||||
Status: m.TmpUserRevoked,
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(&cmd); err != nil {
|
||||
return ApiError(500, "Failed to update invite status", err)
|
||||
}
|
||||
|
||||
return ApiSuccess("Invite revoked")
|
||||
}
|
||||
|
||||
func GetInviteInfoByCode(c *middleware.Context) Response {
|
||||
query := m.GetTempUserByCodeQuery{Code: c.Params(":code")}
|
||||
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
if err == m.ErrTempUserNotFound {
|
||||
return ApiError(404, "Invite not found", nil)
|
||||
}
|
||||
return ApiError(500, "Failed to get invite", err)
|
||||
}
|
||||
|
||||
invite := query.Result
|
||||
|
||||
return Json(200, dtos.InviteInfo{
|
||||
Email: invite.Email,
|
||||
Name: invite.Name,
|
||||
Username: invite.Email,
|
||||
InvitedBy: util.StringsFallback3(invite.InvitedByName, invite.InvitedByLogin, invite.InvitedByEmail),
|
||||
})
|
||||
}
|
||||
|
||||
func CompleteInvite(c *middleware.Context, completeInvite dtos.CompleteInviteForm) Response {
|
||||
query := m.GetTempUserByCodeQuery{Code: completeInvite.InviteCode}
|
||||
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
if err == m.ErrTempUserNotFound {
|
||||
return ApiError(404, "Invite not found", nil)
|
||||
}
|
||||
return ApiError(500, "Failed to get invite", err)
|
||||
}
|
||||
|
||||
invite := query.Result
|
||||
if invite.Status != m.TmpUserInvitePending {
|
||||
return ApiError(412, fmt.Sprintf("Invite cannot be used in status %s", invite.Status), nil)
|
||||
}
|
||||
|
||||
cmd := m.CreateUserCommand{
|
||||
Email: completeInvite.Email,
|
||||
Name: completeInvite.Name,
|
||||
Login: completeInvite.Username,
|
||||
Password: completeInvite.Password,
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(&cmd); err != nil {
|
||||
return ApiError(500, "failed to create user", err)
|
||||
}
|
||||
|
||||
user := cmd.Result
|
||||
|
||||
bus.Publish(&events.UserSignedUp{
|
||||
Id: user.Id,
|
||||
Name: user.Name,
|
||||
Email: user.Email,
|
||||
Login: user.Login,
|
||||
})
|
||||
|
||||
// add to org
|
||||
addOrgUserCmd := m.AddOrgUserCommand{OrgId: invite.OrgId, UserId: user.Id, Role: invite.Role}
|
||||
if err := bus.Dispatch(&addOrgUserCmd); err != nil {
|
||||
return ApiError(500, "Error while trying to create org user", err)
|
||||
}
|
||||
|
||||
// set org to active
|
||||
if err := bus.Dispatch(&m.SetUsingOrgCommand{OrgId: invite.OrgId, UserId: user.Id}); err != nil {
|
||||
return ApiError(500, "Failed to set org as active", err)
|
||||
}
|
||||
|
||||
// update temp user status
|
||||
updateTmpUserCmd := m.UpdateTempUserStatusCommand{Code: invite.Code, Status: m.TmpUserCompleted}
|
||||
if err := bus.Dispatch(&updateTmpUserCmd); err != nil {
|
||||
return ApiError(500, "Failed to update invite status", err)
|
||||
}
|
||||
|
||||
loginUserWithUser(&user, c)
|
||||
|
||||
metrics.M_Api_User_SignUp.Inc(1)
|
||||
metrics.M_Api_User_SignUpInvite.Inc(1)
|
||||
|
||||
return ApiSuccess("User created and logged in")
|
||||
}
|
||||
@@ -14,6 +14,7 @@ var (
|
||||
M_Api_Status_404 = NewComboCounterRef("api.status.404")
|
||||
|
||||
M_Api_User_SignUp = NewComboCounterRef("api.user.signup")
|
||||
M_Api_User_SignUpInvite = NewComboCounterRef("api.user.signup_invite")
|
||||
M_Api_Dashboard_Get = NewComboCounterRef("api.dashboard.get")
|
||||
M_Api_Dashboard_Post = NewComboCounterRef("api.dashboard.post")
|
||||
M_Api_Admin_User_Create = NewComboCounterRef("api.admin.user_create")
|
||||
|
||||
@@ -7,9 +7,10 @@ import (
|
||||
|
||||
// Typed errors
|
||||
var (
|
||||
ErrInvalidRoleType = errors.New("Invalid role type")
|
||||
ErrLastOrgAdmin = errors.New("Cannot remove last organization admin")
|
||||
ErrOrgUserNotFound = errors.New("Cannot find the organization user")
|
||||
ErrInvalidRoleType = errors.New("Invalid role type")
|
||||
ErrLastOrgAdmin = errors.New("Cannot remove last organization admin")
|
||||
ErrOrgUserNotFound = errors.New("Cannot find the organization user")
|
||||
ErrOrgUserAlreadyAdded = errors.New("User is already added to organization")
|
||||
)
|
||||
|
||||
type RoleType string
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Typed errors
|
||||
var (
|
||||
ErrTempUserNotFound = errors.New("User not found")
|
||||
)
|
||||
|
||||
type TempUserStatus string
|
||||
|
||||
const (
|
||||
TmpUserInvitePending TempUserStatus = "InvitePending"
|
||||
TmpUserCompleted TempUserStatus = "Completed"
|
||||
TmpUserEmailPending TempUserStatus = "EmailPending"
|
||||
TmpUserRevoked TempUserStatus = "Revoked"
|
||||
)
|
||||
|
||||
// TempUser holds data for org invites and unconfirmed sign ups
|
||||
type TempUser struct {
|
||||
Id int64
|
||||
OrgId int64
|
||||
Version int
|
||||
Email string
|
||||
Name string
|
||||
Role RoleType
|
||||
InvitedByUserId int64
|
||||
Status TempUserStatus
|
||||
|
||||
EmailSent bool
|
||||
EmailSentOn time.Time
|
||||
Code string
|
||||
RemoteAddr string
|
||||
|
||||
Created time.Time
|
||||
Updated time.Time
|
||||
}
|
||||
|
||||
// ---------------------
|
||||
// COMMANDS
|
||||
|
||||
type CreateTempUserCommand struct {
|
||||
Email string
|
||||
Name string
|
||||
OrgId int64
|
||||
InvitedByUserId int64
|
||||
Status TempUserStatus
|
||||
Code string
|
||||
Role RoleType
|
||||
RemoteAddr string
|
||||
|
||||
Result *TempUser
|
||||
}
|
||||
|
||||
type UpdateTempUserStatusCommand struct {
|
||||
Code string
|
||||
Status TempUserStatus
|
||||
}
|
||||
|
||||
type GetTempUsersForOrgQuery struct {
|
||||
OrgId int64
|
||||
Status TempUserStatus
|
||||
|
||||
Result []*TempUserDTO
|
||||
}
|
||||
|
||||
type GetTempUserByCodeQuery struct {
|
||||
Code string
|
||||
|
||||
Result *TempUserDTO
|
||||
}
|
||||
|
||||
type TempUserDTO struct {
|
||||
Id int64 `json:"id"`
|
||||
OrgId int64 `json:"orgId"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Role RoleType `json:"role"`
|
||||
InvitedByLogin string `json:"invitedByLogin"`
|
||||
InvitedByEmail string `json:"invitedByEmail"`
|
||||
InvitedByName string `json:"invitedByName"`
|
||||
Code string `json:"code"`
|
||||
Status TempUserStatus `json:"status"`
|
||||
Url string `json:"url"`
|
||||
EmailSent bool `json:"emailSent"`
|
||||
EmailSentOn time.Time `json:"emailSentOn"`
|
||||
Created time.Time `json:"createdOn"`
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
func AddMigrations(mg *Migrator) {
|
||||
addMigrationLogMigrations(mg)
|
||||
addUserMigrations(mg)
|
||||
addTempUserMigrations(mg)
|
||||
addStarMigrations(mg)
|
||||
addOrgMigrations(mg)
|
||||
addDashboardMigration(mg)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package migrations
|
||||
|
||||
import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
|
||||
func addTempUserMigrations(mg *Migrator) {
|
||||
tempUserV1 := Table{
|
||||
Name: "temp_user",
|
||||
Columns: []*Column{
|
||||
{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
|
||||
{Name: "org_id", Type: DB_BigInt, Nullable: false},
|
||||
{Name: "version", Type: DB_Int, Nullable: false},
|
||||
{Name: "email", Type: DB_NVarchar, Length: 255},
|
||||
{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: true},
|
||||
{Name: "role", Type: DB_NVarchar, Length: 20, Nullable: true},
|
||||
{Name: "code", Type: DB_NVarchar, Length: 255},
|
||||
{Name: "status", Type: DB_Varchar, Length: 20},
|
||||
{Name: "invited_by_user_id", Type: DB_BigInt, Nullable: true},
|
||||
{Name: "email_sent", Type: DB_Bool},
|
||||
{Name: "email_sent_on", Type: DB_DateTime, Nullable: true},
|
||||
{Name: "remote_addr", Type: DB_Varchar, Nullable: true},
|
||||
{Name: "created", Type: DB_DateTime},
|
||||
{Name: "updated", Type: DB_DateTime},
|
||||
},
|
||||
Indices: []*Index{
|
||||
{Cols: []string{"email"}, Type: IndexType},
|
||||
{Cols: []string{"org_id"}, Type: IndexType},
|
||||
{Cols: []string{"code"}, Type: IndexType},
|
||||
{Cols: []string{"status"}, Type: IndexType},
|
||||
},
|
||||
}
|
||||
|
||||
// addDropAllIndicesMigrations(mg, "v7", tempUserV1)
|
||||
// mg.AddMigration("Drop old table tempUser v7", NewDropTableMigration("temp_user"))
|
||||
|
||||
// create table
|
||||
mg.AddMigration("create temp user table v1-7", NewAddTableMigration(tempUserV1))
|
||||
addTableIndicesMigrations(mg, "v1-7", tempUserV1)
|
||||
}
|
||||
@@ -19,6 +19,12 @@ func init() {
|
||||
|
||||
func AddOrgUser(cmd *m.AddOrgUserCommand) error {
|
||||
return inTransaction(func(sess *xorm.Session) error {
|
||||
// check if user exists
|
||||
if res, err := sess.Query("SELECT 1 from org_user WHERE org_id=? and user_id=?", cmd.OrgId, cmd.UserId); err != nil {
|
||||
return err
|
||||
} else if len(res) == 1 {
|
||||
return m.ErrOrgUserAlreadyAdded
|
||||
}
|
||||
|
||||
entity := m.OrgUser{
|
||||
OrgId: cmd.OrgId,
|
||||
|
||||
@@ -1 +1 @@
|
||||
-timeout=10s
|
||||
-timeout=20s
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
func init() {
|
||||
bus.AddHandler("sql", CreateTempUser)
|
||||
bus.AddHandler("sql", GetTempUsersForOrg)
|
||||
bus.AddHandler("sql", UpdateTempUserStatus)
|
||||
bus.AddHandler("sql", GetTempUserByCode)
|
||||
}
|
||||
|
||||
func UpdateTempUserStatus(cmd *m.UpdateTempUserStatusCommand) error {
|
||||
return inTransaction(func(sess *xorm.Session) error {
|
||||
var rawSql = "UPDATE temp_user SET status=? WHERE code=?"
|
||||
_, err := sess.Exec(rawSql, string(cmd.Status), cmd.Code)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func CreateTempUser(cmd *m.CreateTempUserCommand) error {
|
||||
return inTransaction2(func(sess *session) error {
|
||||
|
||||
// create user
|
||||
user := &m.TempUser{
|
||||
Email: cmd.Email,
|
||||
Name: cmd.Name,
|
||||
OrgId: cmd.OrgId,
|
||||
Code: cmd.Code,
|
||||
Role: cmd.Role,
|
||||
Status: cmd.Status,
|
||||
RemoteAddr: cmd.RemoteAddr,
|
||||
InvitedByUserId: cmd.InvitedByUserId,
|
||||
Created: time.Now(),
|
||||
Updated: time.Now(),
|
||||
}
|
||||
|
||||
if _, err := sess.Insert(user); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.Result = user
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func GetTempUsersForOrg(query *m.GetTempUsersForOrgQuery) error {
|
||||
var rawSql = `SELECT
|
||||
tu.id as id,
|
||||
tu.org_id as org_id,
|
||||
tu.email as email,
|
||||
tu.name as name,
|
||||
tu.role as role,
|
||||
tu.code as code,
|
||||
tu.status as status,
|
||||
tu.email_sent as email_sent,
|
||||
tu.email_sent_on as email_sent_on,
|
||||
tu.created as created,
|
||||
u.login as invited_by_login,
|
||||
u.name as invited_by_name,
|
||||
u.email as invited_by_email
|
||||
FROM ` + dialect.Quote("temp_user") + ` as tu
|
||||
LEFT OUTER JOIN ` + dialect.Quote("user") + ` as u on u.id = tu.invited_by_user_id
|
||||
WHERE tu.org_id=? AND tu.status =? ORDER BY tu.created desc`
|
||||
|
||||
query.Result = make([]*m.TempUserDTO, 0)
|
||||
sess := x.Sql(rawSql, query.OrgId, string(query.Status))
|
||||
err := sess.Find(&query.Result)
|
||||
return err
|
||||
}
|
||||
|
||||
func GetTempUserByCode(query *m.GetTempUserByCodeQuery) error {
|
||||
var rawSql = `SELECT
|
||||
tu.id as id,
|
||||
tu.org_id as org_id,
|
||||
tu.email as email,
|
||||
tu.name as name,
|
||||
tu.role as role,
|
||||
tu.code as code,
|
||||
tu.status as status,
|
||||
tu.email_sent as email_sent,
|
||||
tu.email_sent_on as email_sent_on,
|
||||
tu.created as created,
|
||||
u.login as invited_by_login,
|
||||
u.name as invited_by_name,
|
||||
u.email as invited_by_email
|
||||
FROM ` + dialect.Quote("temp_user") + ` as tu
|
||||
LEFT OUTER JOIN ` + dialect.Quote("user") + ` as u on u.id = tu.invited_by_user_id
|
||||
WHERE tu.code=?`
|
||||
|
||||
var tempUser m.TempUserDTO
|
||||
sess := x.Sql(rawSql, query.Code)
|
||||
has, err := sess.Get(&tempUser)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has == false {
|
||||
return m.ErrTempUserNotFound
|
||||
}
|
||||
|
||||
query.Result = &tempUser
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
func TestTempUserCommandsAndQueries(t *testing.T) {
|
||||
|
||||
Convey("Testing Temp User commands & queries", t, func() {
|
||||
InitTestDB(t)
|
||||
|
||||
Convey("Given saved api key", func() {
|
||||
cmd := m.CreateTempUserCommand{
|
||||
OrgId: 2256,
|
||||
Name: "hello",
|
||||
Code: "asd",
|
||||
Email: "e@as.co",
|
||||
Status: m.TmpUserInvitePending,
|
||||
}
|
||||
err := CreateTempUser(&cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("Should be able to get temp users by org id", func() {
|
||||
query := m.GetTempUsersForOrgQuery{OrgId: 2256, Status: m.TmpUserInvitePending}
|
||||
err = GetTempUsersForOrg(&query)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(len(query.Result), ShouldEqual, 1)
|
||||
})
|
||||
|
||||
Convey("Should be able to get temp users by code", func() {
|
||||
query := m.GetTempUserByCodeQuery{Code: "asd"}
|
||||
err = GetTempUserByCode(&query)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(query.Result.Name, ShouldEqual, "hello")
|
||||
})
|
||||
|
||||
Convey("Should be able update status", func() {
|
||||
cmd2 := m.UpdateTempUserStatusCommand{Code: "asd", Status: m.TmpUserRevoked}
|
||||
err := UpdateTempUserStatus(&cmd2)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package util
|
||||
|
||||
func StringsFallback2(val1 string, val2 string) string {
|
||||
if val1 != "" {
|
||||
return val1
|
||||
}
|
||||
return val2
|
||||
}
|
||||
|
||||
func StringsFallback3(val1 string, val2 string, val3 string) string {
|
||||
if val1 != "" {
|
||||
return val1
|
||||
}
|
||||
if val2 != "" {
|
||||
return val2
|
||||
}
|
||||
return val3
|
||||
}
|
||||
+3
-1
@@ -12,6 +12,7 @@ define([
|
||||
'angular-sanitize',
|
||||
'angular-strap',
|
||||
'angular-dragdrop',
|
||||
'angular-ui',
|
||||
'extend-jquery',
|
||||
'bindonce',
|
||||
],
|
||||
@@ -64,7 +65,8 @@ function (angular, $, _, appLevelRequire) {
|
||||
'$strap.directives',
|
||||
'ang-drag-drop',
|
||||
'grafana',
|
||||
'pasvaz.bindonce'
|
||||
'pasvaz.bindonce',
|
||||
'ui.bootstrap.tabs',
|
||||
];
|
||||
|
||||
var module_types = ['controllers', 'directives', 'factories', 'services', 'filters', 'routes'];
|
||||
|
||||
@@ -17,6 +17,7 @@ require.config({
|
||||
'angular-sanitize': '../vendor/angular-sanitize/angular-sanitize',
|
||||
'angular-dragdrop': '../vendor/angular-native-dragdrop/draganddrop',
|
||||
'angular-strap': '../vendor/angular-other/angular-strap',
|
||||
'angular-ui': '../vendor/angular-ui/angular-bootstrap',
|
||||
timepicker: '../vendor/angular-other/timepicker',
|
||||
datepicker: '../vendor/angular-other/datepicker',
|
||||
bindonce: '../vendor/angular-bindonce/bindonce',
|
||||
@@ -90,6 +91,7 @@ require.config({
|
||||
'angular-dragdrop': ['jquery', 'angular'],
|
||||
'angular-mocks': ['angular'],
|
||||
'angular-sanitize': ['angular'],
|
||||
'angular-ui': ['angular'],
|
||||
'angular-route': ['angular'],
|
||||
'angular-strap': ['angular', 'bootstrap','timepicker', 'datepicker'],
|
||||
'bindonce': ['angular'],
|
||||
|
||||
@@ -6,6 +6,7 @@ define([
|
||||
'./inspectCtrl',
|
||||
'./jsonEditorCtrl',
|
||||
'./loginCtrl',
|
||||
'./invitedCtrl',
|
||||
'./resetPasswordCtrl',
|
||||
'./sidemenuCtrl',
|
||||
'./errorCtrl',
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
define([
|
||||
'angular',
|
||||
'config',
|
||||
],
|
||||
function (angular, config) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('InvitedCtrl', function($scope, $routeParams, contextSrv, backendSrv) {
|
||||
|
||||
contextSrv.sidemenu = false;
|
||||
|
||||
$scope.formModel = {};
|
||||
|
||||
$scope.init = function() {
|
||||
backendSrv.get('/api/user/invite/' + $routeParams.code).then(function(invite) {
|
||||
$scope.formModel.name = invite.name;
|
||||
$scope.formModel.email = invite.email;
|
||||
$scope.formModel.username = invite.email;
|
||||
$scope.formModel.inviteCode = $routeParams.code;
|
||||
|
||||
$scope.greeting = invite.name || invite.email || invite.username;
|
||||
$scope.invitedBy = invite.invitedBy;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.submit = function() {
|
||||
if (!$scope.inviteForm.$valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
backendSrv.post('/api/user/invite/complete', $scope.formModel).then(function() {
|
||||
window.location.href = config.appSubUrl + '/';
|
||||
});
|
||||
};
|
||||
|
||||
$scope.init();
|
||||
|
||||
});
|
||||
});
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="page-container">
|
||||
<div class="page">
|
||||
<h2>
|
||||
User details
|
||||
Edit User
|
||||
</h2>
|
||||
|
||||
<form name="userForm">
|
||||
@@ -17,7 +17,7 @@
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px">
|
||||
<strong>Name</strong>
|
||||
Name
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" required ng-model="user.name" class="input-xxlarge tight-form-input last" >
|
||||
@@ -28,7 +28,7 @@
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px">
|
||||
<strong>Email</strong>
|
||||
Email
|
||||
</li>
|
||||
<li>
|
||||
<input type="email" ng-model="user.email" class="input-xxlarge tight-form-input last" >
|
||||
@@ -39,7 +39,7 @@
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px">
|
||||
<strong>Username</strong>
|
||||
Username
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" ng-model="user.login" class="input-xxlarge tight-form-input last" >
|
||||
@@ -53,16 +53,16 @@
|
||||
<button type="submit" class="pull-right btn btn-success" ng-click="update()" ng-show="!createMode">Update</button>
|
||||
</form>
|
||||
|
||||
<h2>
|
||||
<h3>
|
||||
Change password
|
||||
</h2>
|
||||
</h3>
|
||||
|
||||
<form name="passwordForm">
|
||||
<div>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px">
|
||||
<strong>New password</strong>
|
||||
New password
|
||||
</li>
|
||||
<li>
|
||||
<input type="password" required ng-minlength="4" ng-model="password" class="input-xxlarge tight-form-input last">
|
||||
@@ -76,9 +76,9 @@
|
||||
<button type="submit" class="pull-right btn btn-success" ng-click="setPassword()">Update</button>
|
||||
</form>
|
||||
|
||||
<h2>
|
||||
<h3>
|
||||
Permissions
|
||||
</h2>
|
||||
</h3>
|
||||
|
||||
<div>
|
||||
<div class="tight-form last">
|
||||
@@ -97,9 +97,9 @@
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<h2>
|
||||
<h3>
|
||||
Organizations
|
||||
</h2>
|
||||
</h3>
|
||||
|
||||
<form name="addOrgForm">
|
||||
<div class="tight-form">
|
||||
|
||||
@@ -7,7 +7,7 @@ function(angular, _) {
|
||||
|
||||
var module = angular.module('grafana.services');
|
||||
|
||||
module.service('unsavedChangesSrv', function($modal, $q, $location, $timeout, contextSrv, $window) {
|
||||
module.service('unsavedChangesSrv', function($rootScope, $q, $location, $timeout, contextSrv, $window) {
|
||||
|
||||
function Tracker(dashboard, scope) {
|
||||
var self = this;
|
||||
@@ -142,17 +142,10 @@ function(angular, _) {
|
||||
tracker.scope.$emit('save-dashboard');
|
||||
};
|
||||
|
||||
var confirmModal = $modal({
|
||||
template: './app/partials/unsaved-changes.html',
|
||||
modalClass: 'confirm-modal',
|
||||
persist: false,
|
||||
show: false,
|
||||
$rootScope.appEvent('show-modal', {
|
||||
src: './app/partials/unsaved-changes.html',
|
||||
modalClass: 'modal-no-header confirm-modal',
|
||||
scope: modalScope,
|
||||
keyboard: false
|
||||
});
|
||||
|
||||
$q.when(confirmModal).then(function(modalEl) {
|
||||
modalEl.modal('show');
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ define([
|
||||
'./datasourceEditCtrl',
|
||||
'./orgUsersCtrl',
|
||||
'./newOrgCtrl',
|
||||
'./userInviteCtrl',
|
||||
'./orgApiKeysCtrl',
|
||||
'./orgDetailsCtrl',
|
||||
], function () {});
|
||||
|
||||
@@ -13,14 +13,21 @@ function (angular) {
|
||||
role: 'Viewer',
|
||||
};
|
||||
|
||||
$scope.users = [];
|
||||
$scope.pendingInvites = [];
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.get();
|
||||
$scope.editor = { index: 0 };
|
||||
};
|
||||
|
||||
$scope.get = function() {
|
||||
backendSrv.get('/api/org/users').then(function(users) {
|
||||
$scope.users = users;
|
||||
});
|
||||
backendSrv.get('/api/org/invites').then(function(pendingInvites) {
|
||||
$scope.pendingInvites = pendingInvites;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.updateOrgUser = function(user) {
|
||||
@@ -31,9 +38,26 @@ function (angular) {
|
||||
backendSrv.delete('/api/org/users/' + user.userId).then($scope.get);
|
||||
};
|
||||
|
||||
$scope.addUser = function() {
|
||||
if (!$scope.form.$valid) { return; }
|
||||
backendSrv.post('/api/org/users', $scope.user).then($scope.get);
|
||||
$scope.revokeInvite = function(invite, evt) {
|
||||
evt.stopPropagation();
|
||||
backendSrv.patch('/api/org/invites/' + invite.code + '/revoke').then($scope.get);
|
||||
};
|
||||
|
||||
$scope.copyInviteToClipboard = function(evt) {
|
||||
evt.stopPropagation();
|
||||
};
|
||||
|
||||
$scope.openInviteModal = function() {
|
||||
var modalScope = $scope.$new();
|
||||
modalScope.invitesSent = function() {
|
||||
$scope.get();
|
||||
};
|
||||
|
||||
$scope.appEvent('show-modal', {
|
||||
src: './app/features/org/partials/invite.html',
|
||||
modalClass: 'modal-no-header invite-modal',
|
||||
scope: modalScope
|
||||
});
|
||||
};
|
||||
|
||||
$scope.init();
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<div class="modal-body" ng-controller="UserInviteCtrl" ng-init="init()">
|
||||
|
||||
<a class="modal-close" ng-click="dismiss();">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
|
||||
<h3>
|
||||
Invite Users
|
||||
</h3>
|
||||
|
||||
<div class="modal-tagline">
|
||||
Send invite or add existing Grafana users to the organization
|
||||
<span class="highlight-word">{{contextSrv.user.orgName}}</span>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<form name="inviteForm">
|
||||
<div style="display: inline-block">
|
||||
<div>
|
||||
<div class="tight-form" ng-repeat="invite in invites">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item">
|
||||
Email or Username
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" ng-model="invite.loginOrEmail" required class="input-large tight-form-input" placeholder="email@test.com">
|
||||
</li>
|
||||
<li class="tight-form-item">
|
||||
Name
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" ng-model="invite.name" class="input-large tight-form-input" placeholder="name (optional)">
|
||||
</li>
|
||||
|
||||
<li class="tight-form-item">
|
||||
Role
|
||||
</li>
|
||||
<li>
|
||||
<select ng-model="invite.role" class="input-small tight-form-input" ng-options="f for f in ['Viewer', 'Editor', 'Read Only Editor', 'Admin']">
|
||||
</select>
|
||||
</li>
|
||||
<li class="tight-form-item last" ng-show="$index > 0">
|
||||
<a class="pointer" tabindex="1" ng-click="removeInvite(invite)">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
</li>
|
||||
<div class="clearfix"></div>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="text-align: left; margin-top: 6px;">
|
||||
<a ng-click="addInvite()">+ Invite another</a>
|
||||
<div class="form-inline" style="margin-top: 20px">
|
||||
<editor-checkbox text="Skip sending invite email" model="options.skipEmails" change="targetBlur()"></editor-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="" style="margin-top: 30px; margin-bottom: 20px;">
|
||||
<button type="button" class="btn btn-inverse" ng-click="dismiss()">Cancel</button>
|
||||
<button type="submit" class="btn btn-success" ng-click="sendInvites();">Invite Users</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -9,53 +9,67 @@
|
||||
|
||||
<h2>Organization users</h2>
|
||||
|
||||
<form name="form">
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 127px">
|
||||
<strong>Username or Email</strong>
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" ng-model="user.loginOrEmail" required class="input-xlarge tight-form-input" placeholder="user@email.com or username">
|
||||
</li>
|
||||
<li class="tight-form-item">
|
||||
role
|
||||
</li>
|
||||
<li>
|
||||
<select type="text" ng-model="user.role" class="input-medium tight-form-input" ng-options="f for f in ['Viewer', 'Editor', 'Read Only Editor', 'Admin']">
|
||||
</select>
|
||||
</li>
|
||||
<li>
|
||||
<button class="btn btn-success tight-form-btn" ng-click="addUser()">Add</button>
|
||||
</li>
|
||||
<div class="clearfix"></div>
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
<button class="btn btn-success pull-right" ng-click="openInviteModal()">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add or Invite
|
||||
</button>
|
||||
|
||||
<br>
|
||||
|
||||
<table class="grafana-options-table form-inline">
|
||||
<tr>
|
||||
<th>Login</th>
|
||||
<th>Email</th>
|
||||
<th>Role</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr ng-repeat="user in users">
|
||||
<td>{{user.login}}</td>
|
||||
<td>{{user.email}}</td>
|
||||
<td>
|
||||
<select type="text" ng-model="user.role" class="input-medium" ng-options="f for f in ['Viewer', 'Editor', 'Read Only Editor', 'Admin']" ng-change="updateOrgUser(user)">
|
||||
</select>
|
||||
</td>
|
||||
<td style="width: 1%">
|
||||
<a ng-click="removeUser(user)" class="btn btn-danger btn-mini">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<tabset>
|
||||
<tab heading="Users ({{users.length}})">
|
||||
<table class="grafana-options-table form-inline">
|
||||
<tr>
|
||||
<th>Login</th>
|
||||
<th>Email</th>
|
||||
<th>Role</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr ng-repeat="user in users">
|
||||
<td>{{user.login}}</td>
|
||||
<td>{{user.email}}</td>
|
||||
<td>
|
||||
<select type="text" ng-model="user.role" class="input-medium" ng-options="f for f in ['Viewer', 'Editor', 'Read Only Editor', 'Admin']" ng-change="updateOrgUser(user)">
|
||||
</select>
|
||||
</td>
|
||||
<td style="width: 1%">
|
||||
<a ng-click="removeUser(user)" class="btn btn-danger btn-mini">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</tab>
|
||||
<tab heading="Pending Invitations ({{pendingInvites.length}})">
|
||||
<div class="grafana-list-item" ng-repeat="invite in pendingInvites" ng-click="invite.expanded = !invite.expanded">
|
||||
{{invite.email}}
|
||||
<span ng-show="invite.name" style="padding-left: 20px"> {{invite.name}}</span>
|
||||
<span class="pull-right">
|
||||
<button class="btn btn-inverse btn-mini " data-clipboard-text="{{invite.url}}" clipboard-button ng-click="copyInviteToClipboard($event)"
|
||||
<i class="fa fa-clipboard"></i> Copy Invite
|
||||
</button>
|
||||
|
||||
<a class="pointer">
|
||||
<i ng-show="!invite.expanded" class="fa fa-caret-right"></i>
|
||||
<i ng-show="invite.expanded" class="fa fa-caret-down"></i>
|
||||
</a>
|
||||
</span>
|
||||
<div ng-show="invite.expanded">
|
||||
<a href="{{invite.url}}">{{invite.url}}</a><br>
|
||||
<button class="btn btn-inverse btn-mini">
|
||||
<i class="fa fa-envelope-o"></i> Resend invite
|
||||
</button>
|
||||
|
||||
<button class="btn btn-inverse btn-mini" ng-click="revokeInvite(invite, $event)">
|
||||
<i class="fa fa-remove" style="color: red"></i> Revoke invite
|
||||
</button>
|
||||
<span style="padding-left: 15px">
|
||||
Invited: <em> {{invite.createdOn | date: 'shortDate'}} by {{invite.invitedBy}} </em>
|
||||
</span>
|
||||
<div>
|
||||
</div>
|
||||
</tab>
|
||||
</tabset>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
define([
|
||||
'angular',
|
||||
'lodash',
|
||||
],
|
||||
function (angular, _) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('UserInviteCtrl', function($scope, backendSrv) {
|
||||
|
||||
$scope.invites = [
|
||||
{name: '', email: '', role: 'Editor'},
|
||||
];
|
||||
|
||||
$scope.options = {skipEmails: false};
|
||||
$scope.init = function() { };
|
||||
|
||||
$scope.addInvite = function() {
|
||||
$scope.invites.push({name: '', email: '', role: 'Editor'});
|
||||
};
|
||||
|
||||
$scope.removeInvite = function(invite) {
|
||||
$scope.invites = _.without($scope.invites, invite);
|
||||
};
|
||||
|
||||
$scope.sendInvites = function() {
|
||||
if (!$scope.inviteForm.$valid) { return; }
|
||||
$scope.sendSingleInvite(0);
|
||||
};
|
||||
|
||||
$scope.sendSingleInvite = function(index) {
|
||||
var invite = $scope.invites[index];
|
||||
invite.skipEmails = $scope.options.skipEmails;
|
||||
|
||||
return backendSrv.post('/api/org/invites', invite).finally(function() {
|
||||
index += 1;
|
||||
|
||||
if (index === $scope.invites.length) {
|
||||
$scope.invitesSent();
|
||||
$scope.dismiss();
|
||||
} else {
|
||||
$scope.sendSingleInvite(index);
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
});
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="page-container">
|
||||
<div class="page">
|
||||
|
||||
<h2>Profile details</h2>
|
||||
<h2>Profile</h2>
|
||||
|
||||
<form name="userForm">
|
||||
<div>
|
||||
@@ -64,7 +64,7 @@
|
||||
<button type="submit" class="pull-right btn btn-success" ng-click="update()">Update</button>
|
||||
</form>
|
||||
|
||||
<h2>Organizations</h2>
|
||||
<h3>Organizations</h3>
|
||||
|
||||
<table class="grafana-options-table">
|
||||
<tr ng-repeat="org in orgs">
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<li ng-class="{active: active, disabled: disabled}">
|
||||
<a href ng-click="select()" tab-heading-transclude>{{heading}}</a>
|
||||
</li>
|
||||
@@ -0,0 +1,10 @@
|
||||
<div>
|
||||
<ul class="nav nav-{{type || 'tabs'}} nav-tabs-alt" ng-class="{'nav-stacked': vertical, 'nav-justified': justified}" ng-transclude></ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane"
|
||||
ng-repeat="tab in tabs"
|
||||
ng-class="{active: tab.active}"
|
||||
tab-content-transclude="tab">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -12,7 +12,7 @@
|
||||
{{title}}
|
||||
</div>
|
||||
|
||||
<div class="confirm-modal-text">
|
||||
<div class="modal-tagline">
|
||||
{{text}}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<div class="container">
|
||||
<div class="login-page-background">
|
||||
</div>
|
||||
|
||||
<div class="login-box">
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
<div class="container">
|
||||
|
||||
<div class="login-page-background">
|
||||
</div>
|
||||
|
||||
<div class="login-box">
|
||||
|
||||
<div class="login-box-logo">
|
||||
<img src="img/logo_transparent_200x75.png">
|
||||
</div>
|
||||
|
||||
<div class="invite-box">
|
||||
<h3>
|
||||
Hello {{greeting}}.
|
||||
</h3>
|
||||
|
||||
<div class="modal-tagline">
|
||||
<em>{{invitedBy}}</em> has invited you to join Grafana and the organization <span class="highlight-word">{{contextSrv.user.orgName}}</span></br>Please complete the following to accept your invitation and continue:
|
||||
</div>
|
||||
|
||||
<form name="inviteForm" class="login-form">
|
||||
<div class="tight-from-container">
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 128px">
|
||||
Email
|
||||
</li>
|
||||
<li>
|
||||
<input type="email" name="email" class="tight-form-input last" required ng-model='formModel.email' placeholder="Email" style="width: 253px">
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 128px">
|
||||
Name
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" name="name" class="tight-form-input last" ng-model='formModel.name' placeholder="Name (optional)" style="width: 253px">
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 128px">
|
||||
Username
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" name="username" class="tight-form-input last" required ng-model='formModel.username' placeholder="Username" style="width: 253px">
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 128px">
|
||||
Password
|
||||
</li>
|
||||
<li>
|
||||
<input type="password" name="password" class="tight-form-input last" required ng-model="formModel.password" id="inputPassword" style="width: 253px" placeholder="password">
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-left: 147px; width: 254px;">
|
||||
<password-strength password="formModel.password"></password-strength>
|
||||
</div>
|
||||
|
||||
<div class="login-submit-button-row">
|
||||
<button type="submit" class="btn" ng-click="submit();" ng-class="{'btn-inverse': !inviteForm.$valid, 'btn-primary': inviteForm.$valid}">
|
||||
Continue
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
|
||||
<div class="row" style="margin-top: 50px">
|
||||
<div class="version-footer text-center small">
|
||||
Grafana version: {{buildInfo.version}}, commit: {{buildInfo.commit}},
|
||||
build date: {{buildInfo.buildstamp | date: 'yyyy-MM-dd HH:mm:ss' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -97,6 +97,10 @@ define([
|
||||
templateUrl: 'app/partials/login.html',
|
||||
controller : 'LoginCtrl',
|
||||
})
|
||||
.when('/invite/:code', {
|
||||
templateUrl: 'app/partials/signup_invited.html',
|
||||
controller : 'InvitedCtrl',
|
||||
})
|
||||
.when('/user/password/send-reset-email', {
|
||||
templateUrl: 'app/partials/reset_password.html',
|
||||
controller : 'ResetPasswordCtrl',
|
||||
|
||||
@@ -71,7 +71,7 @@ function (angular, _) {
|
||||
var confirmModal = $modal({
|
||||
template: './app/partials/confirm_modal.html',
|
||||
persist: false,
|
||||
modalClass: 'confirm-modal',
|
||||
modalClass: 'modal-no-header confirm-modal',
|
||||
show: false,
|
||||
scope: scope,
|
||||
keyboard: false
|
||||
|
||||
@@ -14,6 +14,7 @@ function (angular) {
|
||||
|
||||
this.showModal = function(e, options) {
|
||||
var modal = $modal({
|
||||
modalClass: options.modalClass,
|
||||
template: options.src,
|
||||
persist: false,
|
||||
show: false,
|
||||
|
||||
@@ -220,6 +220,7 @@ div.subnav {
|
||||
|
||||
li > a:hover,
|
||||
li.active > a,
|
||||
li.active > a:focus,
|
||||
li.active > a:hover {
|
||||
border-color: transparent;
|
||||
background-color: transparent;
|
||||
@@ -547,8 +548,6 @@ a:hover {
|
||||
}
|
||||
|
||||
.modal {
|
||||
.border-radius(1px);
|
||||
border-top: solid 1px lighten(@grayDark, 5%);
|
||||
background-color: @grafanaPanelBackground;
|
||||
}
|
||||
|
||||
|
||||
@@ -159,6 +159,7 @@ div.subnav {
|
||||
|
||||
li > a:hover,
|
||||
li.active > a,
|
||||
li.active > a:focus,
|
||||
li.active > a:hover {
|
||||
border-color: transparent;
|
||||
background-color: transparent;
|
||||
@@ -531,19 +532,6 @@ a.thumbnail {
|
||||
.border-radius(0);
|
||||
}
|
||||
|
||||
.modal {
|
||||
.border-radius(0);
|
||||
background-color: @bodyBackground;
|
||||
&-header {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&-footer {
|
||||
border-top: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.popover {
|
||||
.border-radius(0);
|
||||
|
||||
|
||||
@@ -67,12 +67,6 @@
|
||||
position: relative;
|
||||
border: @grafanaPanelBorder;
|
||||
padding: 20px 20px 60px 49px;
|
||||
|
||||
h2 {
|
||||
color: @textColor;
|
||||
font-weight: normal;
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.page {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@import "type.less";
|
||||
@import "login.less";
|
||||
@import "submenu.less";
|
||||
@import "graph.less";
|
||||
@@ -15,6 +16,7 @@
|
||||
@import "admin.less";
|
||||
@import "validation.less";
|
||||
@import "fonts.less";
|
||||
@import "tabs.less";
|
||||
|
||||
.row-control-inner {
|
||||
padding:0px;
|
||||
@@ -257,18 +259,28 @@
|
||||
td:first-child { text-align: right; }
|
||||
}
|
||||
|
||||
.confirm-modal {
|
||||
.modal-no-header {
|
||||
border: 1px solid @grafanaTargetFuncBackground;
|
||||
max-width: 500px;
|
||||
background-color: @grafanaPanelBackground;
|
||||
text-align: center;
|
||||
|
||||
h3 {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
float: right;
|
||||
font-size: 140%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.modal-tagline {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-modal {
|
||||
max-width: 500px;
|
||||
|
||||
.confirm-modal-icon {
|
||||
padding-top: 41px;
|
||||
font-size: 280%;
|
||||
@@ -282,10 +294,6 @@
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.confirm-modal-text {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.confirm-modal-buttons {
|
||||
margin-top: 35px;
|
||||
margin-bottom: 35px;
|
||||
@@ -354,5 +362,27 @@
|
||||
color: @orange;
|
||||
}
|
||||
|
||||
.highlight-word {
|
||||
color: @orange;
|
||||
}
|
||||
|
||||
.body-copy-emphasis {
|
||||
color: @headingsColor;
|
||||
}
|
||||
|
||||
.signup-page-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-image: url(/img/background_tease.jpg);
|
||||
|
||||
.signup-logo-container {
|
||||
width: 150px;
|
||||
margin: 0 auto;
|
||||
padding: 80px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,4 +93,46 @@
|
||||
}
|
||||
}
|
||||
|
||||
.login-page-background {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-image: url(/img/background_tease.jpg);
|
||||
opacity: 0.05;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.invite-box {
|
||||
text-align: center;
|
||||
border: 1px solid @grafanaTargetFuncBackground;
|
||||
background-color: @grafanaPanelBackground;
|
||||
position: fixed;
|
||||
max-width: 800px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
top: 20%;
|
||||
|
||||
.tight-form {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
float: right;
|
||||
font-size: 140%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.modal-tagline {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,23 +33,11 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.grafana-options-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
max-width: 450px;
|
||||
|
||||
li:nth-child(odd) {
|
||||
background-color: @grafanaListAccent;
|
||||
}
|
||||
|
||||
li {
|
||||
float: left;
|
||||
margin: 2px;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid @grafanaListBorderBottom;
|
||||
border: 1px solid @grafanaListBorderBottom;
|
||||
}
|
||||
li:first-child {
|
||||
border: 1px solid @grafanaListBorderBottom;
|
||||
}
|
||||
.grafana-list-item {
|
||||
display: block;
|
||||
padding: 1px 10px;
|
||||
line-height: 34px;
|
||||
background-color: @grafanaTargetBackground;
|
||||
margin-bottom: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
.nav-tabs-alt {
|
||||
border-bottom: @grafanaTriggerBorder;
|
||||
padding-left: 10px;
|
||||
|
||||
& > li > a {
|
||||
color: darken(@linkColor, 20%);
|
||||
}
|
||||
|
||||
li > a:hover {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
li.active > a,
|
||||
li.active > a:focus,
|
||||
li.active > a:hover {
|
||||
.border-radius(3px);
|
||||
border: @grafanaTriggerBorder;
|
||||
background-color: transparent;
|
||||
border-bottom: 1px solid @grafanaPanelBackground;
|
||||
color: @linkColor;
|
||||
}
|
||||
|
||||
li.disabled > a {
|
||||
color: @textColor;
|
||||
}
|
||||
|
||||
.open .dropdown-toggle {
|
||||
background-color: #060606;
|
||||
border-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ select.tight-form-input {
|
||||
margin: 0px;
|
||||
border-radius: 0;
|
||||
height: 36px;
|
||||
padding: 8px 3px;
|
||||
padding: 9px 3px;
|
||||
&.last {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
//
|
||||
// Typography
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
// Body text
|
||||
// -------------------------
|
||||
|
||||
p {
|
||||
margin: 0 0 @baseLineHeight / 2;
|
||||
}
|
||||
.lead {
|
||||
margin-bottom: @baseLineHeight;
|
||||
font-size: @baseFontSize * 1.5;
|
||||
font-weight: 200;
|
||||
line-height: @baseLineHeight * 1.5;
|
||||
}
|
||||
|
||||
|
||||
// Emphasis & misc
|
||||
// -------------------------
|
||||
|
||||
// Ex: 14px base font * 85% = about 12px
|
||||
small { font-size: 85%; }
|
||||
|
||||
strong { font-weight: 500; }
|
||||
em { font-style: italic; color: @headingsColor; }
|
||||
cite { font-style: normal; }
|
||||
|
||||
// Utility classes
|
||||
.muted { color: @grayLight; }
|
||||
a.muted:hover,
|
||||
a.muted:focus { color: darken(@grayLight, 10%); }
|
||||
|
||||
.text-warning { color: @warningText; }
|
||||
a.text-warning:hover,
|
||||
a.text-warning:focus { color: darken(@warningText, 10%); }
|
||||
|
||||
.text-error { color: @errorText; }
|
||||
a.text-error:hover,
|
||||
a.text-error:focus { color: darken(@errorText, 10%); }
|
||||
|
||||
.text-info { color: @infoText; }
|
||||
a.text-info:hover,
|
||||
a.text-info:focus { color: darken(@infoText, 10%); }
|
||||
|
||||
.text-success { color: @successText; }
|
||||
a.text-success:hover,
|
||||
a.text-success:focus { color: darken(@successText, 10%); }
|
||||
|
||||
.text-left { text-align: left; }
|
||||
.text-right { text-align: right; }
|
||||
.text-center { text-align: center; }
|
||||
|
||||
|
||||
// Headings
|
||||
// -------------------------
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: (@baseLineHeight / 2) 0;
|
||||
font-family: @headingsFontFamily;
|
||||
font-weight: @headingsFontWeight;
|
||||
line-height: @baseLineHeight;
|
||||
color: @headingsColor;
|
||||
text-rendering: optimizelegibility; // Fix the character spacing for headings
|
||||
small {
|
||||
font-weight: normal;
|
||||
line-height: 1;
|
||||
color: @grayLight;
|
||||
}
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3 { line-height: @baseLineHeight * 2; }
|
||||
|
||||
h1 { font-size: @baseFontSize * 2.00; } // ~38px
|
||||
h2 { font-size: @baseFontSize * 1.75; } // ~32px
|
||||
h3 { font-size: @baseFontSize * 1.50; } // ~24px
|
||||
h4 { font-size: @baseFontSize * 1.25; } // ~18px
|
||||
h5 { font-size: @baseFontSize; }
|
||||
h6 { font-size: @baseFontSize * 0.85; } // ~12px
|
||||
|
||||
h1 small { font-size: @baseFontSize * 1.75; } // ~24px
|
||||
h2 small { font-size: @baseFontSize * 1.25; } // ~18px
|
||||
h3 small { font-size: @baseFontSize; }
|
||||
h4 small { font-size: @baseFontSize; }
|
||||
|
||||
|
||||
// Page header
|
||||
// -------------------------
|
||||
|
||||
.page-header {
|
||||
padding-bottom: (@baseLineHeight / 2) - 1;
|
||||
margin: @baseLineHeight 0 (@baseLineHeight * 1.5);
|
||||
border-bottom: 1px solid @grayLighter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Lists
|
||||
// --------------------------------------------------
|
||||
|
||||
// Unordered and Ordered lists
|
||||
ul, ol {
|
||||
padding: 0;
|
||||
margin: 0 0 @baseLineHeight / 2 25px;
|
||||
}
|
||||
ul ul,
|
||||
ul ol,
|
||||
ol ol,
|
||||
ol ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
li {
|
||||
line-height: @baseLineHeight;
|
||||
}
|
||||
|
||||
// Remove default list styles
|
||||
ul.unstyled,
|
||||
ol.unstyled {
|
||||
margin-left: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
// Single-line list items
|
||||
ul.inline,
|
||||
ol.inline {
|
||||
margin-left: 0;
|
||||
list-style: none;
|
||||
> li {
|
||||
display: inline-block;
|
||||
.ie7-inline-block();
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
// Description Lists
|
||||
dl {
|
||||
margin-bottom: @baseLineHeight;
|
||||
}
|
||||
dt,
|
||||
dd {
|
||||
line-height: @baseLineHeight;
|
||||
}
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
dd {
|
||||
margin-left: @baseLineHeight / 2;
|
||||
}
|
||||
// Horizontal layout (like forms)
|
||||
.dl-horizontal {
|
||||
.clearfix(); // Ensure dl clears floats if empty dd elements present
|
||||
dt {
|
||||
float: left;
|
||||
width: @horizontalComponentOffset - 20;
|
||||
clear: left;
|
||||
text-align: right;
|
||||
.text-overflow();
|
||||
}
|
||||
dd {
|
||||
margin-left: @horizontalComponentOffset;
|
||||
}
|
||||
}
|
||||
|
||||
// MISC
|
||||
// ----
|
||||
|
||||
// Horizontal rules
|
||||
hr {
|
||||
margin: @baseLineHeight 0;
|
||||
border: 0;
|
||||
border-top: 1px solid @hrBorder;
|
||||
border-bottom: 1px solid @white;
|
||||
}
|
||||
|
||||
// Abbreviations and acronyms
|
||||
abbr[title],
|
||||
// Added data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257
|
||||
abbr[data-original-title] {
|
||||
cursor: help;
|
||||
border-bottom: 1px dotted @grayLight;
|
||||
}
|
||||
abbr.initialism {
|
||||
font-size: 90%;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
// Blockquotes
|
||||
blockquote {
|
||||
padding: 0 0 0 15px;
|
||||
margin: 0 0 @baseLineHeight;
|
||||
border-left: 5px solid @grayLighter;
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
font-size: @baseFontSize * 1.25;
|
||||
font-weight: 300;
|
||||
line-height: 1.25;
|
||||
}
|
||||
small {
|
||||
display: block;
|
||||
line-height: @baseLineHeight;
|
||||
color: @grayLight;
|
||||
&:before {
|
||||
content: '\2014 \00A0';
|
||||
}
|
||||
}
|
||||
|
||||
// Float right with text-align: right
|
||||
&.pull-right {
|
||||
float: right;
|
||||
padding-right: 15px;
|
||||
padding-left: 0;
|
||||
border-right: 5px solid @grayLighter;
|
||||
border-left: 0;
|
||||
p,
|
||||
small {
|
||||
text-align: right;
|
||||
}
|
||||
small {
|
||||
&:before {
|
||||
content: '';
|
||||
}
|
||||
&:after {
|
||||
content: '\00A0 \2014';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Quotes
|
||||
q:before,
|
||||
q:after,
|
||||
blockquote:before,
|
||||
blockquote:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
// Addresses
|
||||
address {
|
||||
display: block;
|
||||
margin-bottom: @baseLineHeight;
|
||||
font-style: normal;
|
||||
line-height: @baseLineHeight;
|
||||
}
|
||||
@@ -69,8 +69,8 @@
|
||||
@altFontFamily: @serifFontFamily;
|
||||
|
||||
@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily
|
||||
@headingsFontWeight: bold; // instead of browser default, bold
|
||||
@headingsColor: @textColor; // empty to use BS default, @textColor
|
||||
@headingsFontWeight: normal; // instead of browser default, bold
|
||||
@headingsColor: darken(@white,11%); // empty to use BS default, @textColor
|
||||
@inputText: @black;
|
||||
|
||||
|
||||
@@ -98,6 +98,8 @@
|
||||
@grafanaListHighlight: #333;
|
||||
@grafanaListMainLinkColor: @textColor;
|
||||
|
||||
@pageContainerBorderColor: @grayDark;
|
||||
|
||||
// Scrollbars
|
||||
@scrollbarBackground: #3a3a3a;
|
||||
@scrollbarBackground2: #3a3a3a;
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
|
||||
// grafana Variables
|
||||
// -------------------------
|
||||
@grafanaPanelBackground: @white;
|
||||
@grafanaPanelBorder: solid 1px #ddd;
|
||||
@grafanaTriggerBorder: solid 1px @grayLighter;
|
||||
@grafanaPanelBackground: @grayLighter;
|
||||
@grafanaPanelBorder: solid 1px #ddd;
|
||||
@grafanaTriggerBorder: solid 1px @grayLight;
|
||||
|
||||
// Submenu
|
||||
@submenuBackground: rgb(218, 217, 217);
|
||||
@@ -58,16 +58,14 @@
|
||||
|
||||
// Scaffolding
|
||||
// -------------------------
|
||||
@bodyBackground: #EAEAEA;
|
||||
@bodyBackground: #EFEFEF;
|
||||
@textColor: @gray;
|
||||
|
||||
|
||||
// Links
|
||||
// -------------------------
|
||||
@linkColor: @gray;
|
||||
@linkColorDisabled: lighten(@linkColor,30%);
|
||||
@linkColorHover: @grayDarker;
|
||||
|
||||
@linkColorHover: darken(@linkColor, 20%);
|
||||
|
||||
// Typography
|
||||
// -------------------------
|
||||
@@ -76,14 +74,14 @@
|
||||
@monoFontFamily: Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||
|
||||
@baseFontSize: 14px;
|
||||
@baseFontWeight: 400;
|
||||
@baseFontWeight: 400;
|
||||
@baseFontFamily: @sansFontFamily;
|
||||
@baseLineHeight: 20px;
|
||||
@altFontFamily: @serifFontFamily;
|
||||
|
||||
@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily
|
||||
@headingsFontWeight: bold; // instead of browser default, bold
|
||||
@headingsColor: @grayDarker; // empty to use BS default, @textColor
|
||||
@headingsFontWeight: normal; // instead of browser default, bold
|
||||
@headingsColor: @textColor; // empty to use BS default, @textColor
|
||||
|
||||
|
||||
// Component sizing
|
||||
@@ -111,6 +109,7 @@
|
||||
@grafanaListHighlightContrast: #ddd;
|
||||
@grafanaListMainLinkColor: @textColor;
|
||||
|
||||
@pageContainerBorderColor: darken(@grafanaTargetBackground, 5%);
|
||||
|
||||
|
||||
// Tables
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
html files in this folder are generated from templates and build system in repo_root/emails
|
||||
@@ -0,0 +1,198 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
|
||||
</head>
|
||||
<body style="-ms-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px; margin: 0; min-width: 100%; padding: 0; text-align: left; width: 100% !important"><style type="text/css">
|
||||
body {
|
||||
width: 100% !important; min-width: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; margin: 0; padding: 0;
|
||||
}
|
||||
img {
|
||||
outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; width: auto; max-width: 100%; float: left; clear: both; display: block;
|
||||
}
|
||||
body {
|
||||
color: #222222; font-family: "Helvetica", "Arial", sans-serif; font-weight: normal; padding: 0; margin: 0; text-align: left; line-height: 1.3;
|
||||
}
|
||||
body {
|
||||
font-size: 14px; line-height: 19px;
|
||||
}
|
||||
a:hover {
|
||||
color: #2795b6 !important;
|
||||
}
|
||||
a:active {
|
||||
color: #2795b6 !important;
|
||||
}
|
||||
a:visited {
|
||||
color: #2ba6cb !important;
|
||||
}
|
||||
table.button:hover td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:visited td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:active td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:hover td a {
|
||||
color: #fff !important;
|
||||
}
|
||||
table.button:visited td a {
|
||||
color: #fff !important;
|
||||
}
|
||||
table.button:active td a {
|
||||
color: #fff !important;
|
||||
}
|
||||
table.button:hover td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:hover td a {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
table.button:active td a {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
table.button td a:visited {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
body {
|
||||
font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;
|
||||
}
|
||||
@media only screen and (max-width: 600px) {
|
||||
table[class="body"] img {
|
||||
width: auto !important; height: auto !important;
|
||||
}
|
||||
table[class="body"] center {
|
||||
min-width: 0 !important;
|
||||
}
|
||||
table[class="body"] .container {
|
||||
width: 95% !important;
|
||||
}
|
||||
table[class="body"] .row {
|
||||
width: 100% !important; display: block !important;
|
||||
}
|
||||
table[class="body"] .wrapper {
|
||||
display: block !important; padding-right: 0 !important;
|
||||
}
|
||||
table[class="body"] .columns {
|
||||
table-layout: fixed !important; float: none !important; width: 100% !important; padding-right: 0px !important; padding-left: 0px !important; display: block !important;
|
||||
}
|
||||
table[class="body"] table.columns td {
|
||||
width: 100% !important;
|
||||
}
|
||||
table[class="body"] .columns td.six {
|
||||
width: 50% !important;
|
||||
}
|
||||
table[class="body"] table.columns td.expander {
|
||||
width: 1px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<table class="body" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; border-collapse: collapse; border-spacing: 0; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; height: 100%; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="center" align="center" valign="top" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: center; vertical-align: top; word-break: break-word">
|
||||
<center style="min-width: 580px; width: 100%">
|
||||
|
||||
<table class="row header" style="background: #333; border-collapse: collapse; border-spacing: 0; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%" bgcolor="#333">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="center" align="center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: center; vertical-align: top; word-break: break-word" valign="top">
|
||||
<center style="min-width: 580px; width: 100%">
|
||||
|
||||
<table class="container" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: inherit; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="six sub-columns center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; min-width: 0px; padding: 0px 10px 10px 0px; text-align: center; vertical-align: top; width: 50%; word-break: break-word" align="center" valign="top">
|
||||
<img src="http://docs.grafana.org/img/logo_transparent_200x75.png" style="-ms-interpolation-mode: bicubic; clear: both; display: inline; float: none; max-width: 100%; outline: none; text-decoration: none; width: 150px" align="none" />
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="container" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: inherit; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
|
||||
|
||||
{{Subject .Subject "{{.InvitedBy}} has added you to the Grafana organization {{.OrgName}}"}}
|
||||
|
||||
<table class="row" style="border-collapse: collapse; border-spacing: 0; display: block; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0px 0px 10px; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
<h3 style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 32px; font-weight: normal; line-height: 1.3; margin: 0; padding: 0; text-align: left; word-break: normal" align="left">You have been added to the Grafana organization {{.OrgName}}</h3>
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="row" style="border-collapse: collapse; border-spacing: 0; display: block; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0px 0px 10px; text-align: center; vertical-align: top; word-break: break-word" align="center" valign="top">
|
||||
<p style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px; margin: 0 0 10px; padding: 0; text-align: left" align="left">You can switch organization in the left side menu, in the dropdown below your username.</p>
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
<table class="row footer" style="border-collapse: collapse; border-spacing: 0; display: block; margin-top: 20px; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td align="center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0px 0px 10px; text-align: left; vertical-align: top; word-break: break-word" valign="top">
|
||||
<center style="min-width: 580px; width: 100%">
|
||||
<p style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px; margin: 0 0 10px; padding: 0; text-align: center" align="center">
|
||||
Sent by <a href="{{.AppUrl}}" style="color: #2ba6cb; text-decoration: none">Grafana v{{.BuildVersion}}</a>
|
||||
</p>
|
||||
</center>
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,204 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
|
||||
</head>
|
||||
<body style="-ms-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px; margin: 0; min-width: 100%; padding: 0; text-align: left; width: 100% !important"><style type="text/css">
|
||||
body {
|
||||
width: 100% !important; min-width: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; margin: 0; padding: 0;
|
||||
}
|
||||
img {
|
||||
outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; width: auto; max-width: 100%; float: left; clear: both; display: block;
|
||||
}
|
||||
body {
|
||||
color: #222222; font-family: "Helvetica", "Arial", sans-serif; font-weight: normal; padding: 0; margin: 0; text-align: left; line-height: 1.3;
|
||||
}
|
||||
body {
|
||||
font-size: 14px; line-height: 19px;
|
||||
}
|
||||
a:hover {
|
||||
color: #2795b6 !important;
|
||||
}
|
||||
a:active {
|
||||
color: #2795b6 !important;
|
||||
}
|
||||
a:visited {
|
||||
color: #2ba6cb !important;
|
||||
}
|
||||
table.button:hover td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:visited td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:active td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:hover td a {
|
||||
color: #fff !important;
|
||||
}
|
||||
table.button:visited td a {
|
||||
color: #fff !important;
|
||||
}
|
||||
table.button:active td a {
|
||||
color: #fff !important;
|
||||
}
|
||||
table.button:hover td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:hover td a {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
table.button:active td a {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
table.button td a:visited {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
body {
|
||||
font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;
|
||||
}
|
||||
@media only screen and (max-width: 600px) {
|
||||
table[class="body"] img {
|
||||
width: auto !important; height: auto !important;
|
||||
}
|
||||
table[class="body"] center {
|
||||
min-width: 0 !important;
|
||||
}
|
||||
table[class="body"] .container {
|
||||
width: 95% !important;
|
||||
}
|
||||
table[class="body"] .row {
|
||||
width: 100% !important; display: block !important;
|
||||
}
|
||||
table[class="body"] .wrapper {
|
||||
display: block !important; padding-right: 0 !important;
|
||||
}
|
||||
table[class="body"] .columns {
|
||||
table-layout: fixed !important; float: none !important; width: 100% !important; padding-right: 0px !important; padding-left: 0px !important; display: block !important;
|
||||
}
|
||||
table[class="body"] table.columns td {
|
||||
width: 100% !important;
|
||||
}
|
||||
table[class="body"] .columns td.six {
|
||||
width: 50% !important;
|
||||
}
|
||||
table[class="body"] table.columns td.expander {
|
||||
width: 1px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<table class="body" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; border-collapse: collapse; border-spacing: 0; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; height: 100%; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="center" align="center" valign="top" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: center; vertical-align: top; word-break: break-word">
|
||||
<center style="min-width: 580px; width: 100%">
|
||||
|
||||
<table class="row header" style="background: #333; border-collapse: collapse; border-spacing: 0; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%" bgcolor="#333">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="center" align="center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: center; vertical-align: top; word-break: break-word" valign="top">
|
||||
<center style="min-width: 580px; width: 100%">
|
||||
|
||||
<table class="container" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: inherit; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="six sub-columns center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; min-width: 0px; padding: 0px 10px 10px 0px; text-align: center; vertical-align: top; width: 50%; word-break: break-word" align="center" valign="top">
|
||||
<img src="http://docs.grafana.org/img/logo_transparent_200x75.png" style="-ms-interpolation-mode: bicubic; clear: both; display: inline; float: none; max-width: 100%; outline: none; text-decoration: none; width: 150px" align="none" />
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="container" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: inherit; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
|
||||
|
||||
{{Subject .Subject "{{.InvitedBy}} has invited you to join Grafana"}}
|
||||
|
||||
<table class="row" style="border-collapse: collapse; border-spacing: 0; display: block; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0px 0px 10px; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
<h3 style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 32px; font-weight: normal; line-height: 1.3; margin: 0; padding: 0; text-align: left; word-break: normal" align="left">You're invited to sign up to Grafana and join organization {{.OrgName}}</h3>
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="row" style="border-collapse: collapse; border-spacing: 0; display: block; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0px 0px 10px; text-align: center; vertical-align: top; word-break: break-word" align="center" valign="top">
|
||||
<table class="button radius" style="border-collapse: collapse; border-spacing: 0; overflow: hidden; padding: 0; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td style="-moz-border-radius: 3px; -moz-hyphens: auto; -webkit-border-radius: 3px; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; background: #2ba6cb; border-collapse: collapse !important; border-radius: 3px; border: 1px solid #2284a1; color: #ffffff; display: block; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 8px 0; text-align: center; vertical-align: top; width: auto !important; word-break: break-word" align="center" bgcolor="#2ba6cb" valign="top">
|
||||
<a href="{{.LinkUrl}}" style="color: #ffffff; font-family: Helvetica, Arial, sans-serif; font-size: 16px; font-weight: bold; text-decoration: none">Complete Sign Up</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
<table class="row footer" style="border-collapse: collapse; border-spacing: 0; display: block; margin-top: 20px; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td align="center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0px 0px 10px; text-align: left; vertical-align: top; word-break: break-word" valign="top">
|
||||
<center style="min-width: 580px; width: 100%">
|
||||
<p style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px; margin: 0 0 10px; padding: 0; text-align: center" align="center">
|
||||
Sent by <a href="{{.AppUrl}}" style="color: #2ba6cb; text-decoration: none">Grafana v{{.BuildVersion}}</a>
|
||||
</p>
|
||||
</center>
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,71 +1,203 @@
|
||||
{{Subject .Subject "Reset your Grafana password - {{.Name}}"}}
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;">
|
||||
<head>
|
||||
<!-- If you delete this meta tag, Half Life 3 will never be released. -->
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title></title>
|
||||
</head>
|
||||
<body bgcolor="#FFFFFF" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; margin: 0; padding: 0;"><style type="text/css">
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
|
||||
</head>
|
||||
<body style="-ms-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px; margin: 0; min-width: 100%; padding: 0; text-align: left; width: 100% !important"><style type="text/css">
|
||||
body {
|
||||
width: 100% !important; min-width: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; margin: 0; padding: 0;
|
||||
}
|
||||
img {
|
||||
outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; width: auto; max-width: 100%; float: left; clear: both; display: block;
|
||||
}
|
||||
body {
|
||||
color: #222222; font-family: "Helvetica", "Arial", sans-serif; font-weight: normal; padding: 0; margin: 0; text-align: left; line-height: 1.3;
|
||||
}
|
||||
body {
|
||||
font-size: 14px; line-height: 19px;
|
||||
}
|
||||
a:hover {
|
||||
color: #2795b6 !important;
|
||||
}
|
||||
a:active {
|
||||
color: #2795b6 !important;
|
||||
}
|
||||
a:visited {
|
||||
color: #2ba6cb !important;
|
||||
}
|
||||
table.button:hover td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:visited td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:active td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:hover td a {
|
||||
color: #fff !important;
|
||||
}
|
||||
table.button:visited td a {
|
||||
color: #fff !important;
|
||||
}
|
||||
table.button:active td a {
|
||||
color: #fff !important;
|
||||
}
|
||||
table.button:hover td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:hover td a {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
table.button:active td a {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
table.button td a:visited {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
body {
|
||||
font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;
|
||||
}
|
||||
@media only screen and (max-width: 600px) {
|
||||
a[class="btn"] {
|
||||
display: block !important; margin-bottom: 10px !important; background-image: none !important; margin-right: 0 !important;
|
||||
table[class="body"] img {
|
||||
width: auto !important; height: auto !important;
|
||||
}
|
||||
div[class="column"] {
|
||||
width: auto !important; float: none !important;
|
||||
table[class="body"] center {
|
||||
min-width: 0 !important;
|
||||
}
|
||||
table.social div[class="column"] {
|
||||
width: auto !important;
|
||||
table[class="body"] .container {
|
||||
width: 95% !important;
|
||||
}
|
||||
table[class="body"] .row {
|
||||
width: 100% !important; display: block !important;
|
||||
}
|
||||
table[class="body"] .wrapper {
|
||||
display: block !important; padding-right: 0 !important;
|
||||
}
|
||||
table[class="body"] .columns {
|
||||
table-layout: fixed !important; float: none !important; width: 100% !important; padding-right: 0px !important; padding-left: 0px !important; display: block !important;
|
||||
}
|
||||
table[class="body"] table.columns td {
|
||||
width: 100% !important;
|
||||
}
|
||||
table[class="body"] .columns td.six {
|
||||
width: 50% !important;
|
||||
}
|
||||
table[class="body"] table.columns td.expander {
|
||||
width: 1px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<table class="body" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; border-collapse: collapse; border-spacing: 0; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; height: 100%; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="center" align="center" valign="top" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: center; vertical-align: top; word-break: break-word">
|
||||
<center style="min-width: 580px; width: 100%">
|
||||
|
||||
<!-- HEADER -->
|
||||
<table class="head-wrap" bgcolor="#666666" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
||||
<td class="header container" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto; padding: 0;">
|
||||
<table class="row header" style="background: #333; border-collapse: collapse; border-spacing: 0; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%" bgcolor="#333">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="center" align="center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: center; vertical-align: top; word-break: break-word" valign="top">
|
||||
<center style="min-width: 580px; width: 100%">
|
||||
|
||||
<div class="content" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; max-width: 600px; display: block; margin: 0 auto; padding: 15px;">
|
||||
<table style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td align="center" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><img src="http://grafana.org/assets/img/logo_transparent_200x75.png" alt="Grafnaa" style="width: 200px; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; max-width: 100%; margin: 0; padding: 0;" /></td>
|
||||
</tr></table></div>
|
||||
<table class="container" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: inherit; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
|
||||
</td>
|
||||
<td style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
||||
</tr></table><!-- /HEADER --><!-- BODY --><table class="body-wrap" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
||||
<td class="container" bgcolor="#FFFFFF" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto; padding: 0;">
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="six sub-columns center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; min-width: 0px; padding: 0px 10px 10px 0px; text-align: center; vertical-align: top; width: 50%; word-break: break-word" align="center" valign="top">
|
||||
<img src="http://docs.grafana.org/img/logo_transparent_200x75.png" style="-ms-interpolation-mode: bicubic; clear: both; display: inline; float: none; max-width: 100%; outline: none; text-decoration: none; width: 150px" align="none" />
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="content" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; max-width: 600px; display: block; margin: 0 auto; padding: 15px;">
|
||||
<table style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;">
|
||||
<td align="left" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;">
|
||||
<p style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-weight: normal; font-size: 14px; line-height: 1.6; margin: 25px 0 15px; font-weight:600;">Hi {{.Name}},</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-weight: normal; font-size: 14px; line-height: 1.6; margin: 0 0 15px;">Please click the following link to reset your password within <b>{{.EmailCodeValidHours}} hours</b>.</p>
|
||||
<p style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-weight: normal; font-size: 14px; line-height: 1.6; margin: 0 0 15px;">
|
||||
<a href="{{.AppUrl}}/user/password/reset?code={{.Code}}">{{.AppUrl}}user/password/reset?code={{.Code}}</a>
|
||||
</p>
|
||||
<p style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-weight: normal; font-size: 14px; line-height: 1.6; margin: 0 0 15px;"></p>
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="container" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: inherit; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
{{Subject .Subject "Reset your Grafana password - {{.Name}}"}}
|
||||
|
||||
<table class="row" style="border-collapse: collapse; border-spacing: 0; display: block; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0px 0px 10px; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
<h3 style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 32px; font-weight: normal; line-height: 1.3; margin: 0; padding: 0; text-align: left; word-break: normal" align="left">Hi {{.Name}}</h3>
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="row" style="border-collapse: collapse; border-spacing: 0; display: block; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0px 0px 10px; text-align: center; vertical-align: top; word-break: break-word" align="center" valign="top">
|
||||
<p style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px; margin: 0 0 10px; padding: 0; text-align: left" align="left">
|
||||
Please click the following link to reset your password within <strong>{{.EmailCodeValidHours}} hours</strong>.
|
||||
</p>
|
||||
<p style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px; margin: 0 0 10px; padding: 0; text-align: left" align="left">
|
||||
<a href="{{.AppUrl}}user/password/reset?code={{.Code}}" style="color: #2ba6cb; text-decoration: none">{{.AppUrl}}user/password/reset?code={{.Code}}</a>
|
||||
</p>
|
||||
<p style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px; margin: 0 0 10px; padding: 0; text-align: left" align="left">Not working? Try copying and pasting it to your browser.</p>
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td align="center" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 15px;">
|
||||
<p class="callout" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; color: #999; font-weight: normal; font-size: 14px; line-height: 1.6; margin: 0 0 15px;">
|
||||
Not working? Try copying and pasting it to your browser. </br>Otherwise, dont hesitate to email us at <a href="mailto:contact@grafana.org">contact@grafana.org</a>
|
||||
</p><!-- /Callout Panel -->
|
||||
</td>
|
||||
</tr>
|
||||
</table></div><!-- /content -->
|
||||
|
||||
</td>
|
||||
<td style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
||||
</tr></table><!-- /BODY -->
|
||||
<table style="width: 100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<p style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; color: #999; font-weight: normal; font-size: 14px; line-height: 1.6; margin: 0 0 15px; padding: 15px;">© 2015 <a style="color:#13b2d4;text-decoration:none;" target="_blank" href="https://grafana.org">Grafana</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table><!-- /FOOTER -->
|
||||
|
||||
<table class="row footer" style="border-collapse: collapse; border-spacing: 0; display: block; margin-top: 20px; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td align="center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0px 0px 10px; text-align: left; vertical-align: top; word-break: break-word" valign="top">
|
||||
<center style="min-width: 580px; width: 100%">
|
||||
<p style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px; margin: 0 0 10px; padding: 0; text-align: center" align="center">
|
||||
Sent by <a href="{{.AppUrl}}" style="color: #2ba6cb; text-decoration: none">Grafana v{{.BuildVersion}}</a>
|
||||
</p>
|
||||
</center>
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,69 +1,197 @@
|
||||
{{Subject .Subject "Welcome to Grafana"}}
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;">
|
||||
<head>
|
||||
<!-- If you delete this meta tag, Half Life 3 will never be released. -->
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>{{.CheckType}} {{ .State }} for {{.Endpoint}}"}}</title>
|
||||
</head>
|
||||
<body bgcolor="#FFFFFF" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; margin: 0; padding: 0;"><style type="text/css">
|
||||
</head>
|
||||
<body style="-ms-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px; margin: 0; min-width: 100%; padding: 0; text-align: left; width: 100% !important"><style type="text/css">
|
||||
body {
|
||||
width: 100% !important; min-width: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; margin: 0; padding: 0;
|
||||
}
|
||||
img {
|
||||
outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; width: auto; max-width: 100%; float: left; clear: both; display: block;
|
||||
}
|
||||
body {
|
||||
color: #222222; font-family: "Helvetica", "Arial", sans-serif; font-weight: normal; padding: 0; margin: 0; text-align: left; line-height: 1.3;
|
||||
}
|
||||
body {
|
||||
font-size: 14px; line-height: 19px;
|
||||
}
|
||||
a:hover {
|
||||
color: #2795b6 !important;
|
||||
}
|
||||
a:active {
|
||||
color: #2795b6 !important;
|
||||
}
|
||||
a:visited {
|
||||
color: #2ba6cb !important;
|
||||
}
|
||||
table.button:hover td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:visited td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:active td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:hover td a {
|
||||
color: #fff !important;
|
||||
}
|
||||
table.button:visited td a {
|
||||
color: #fff !important;
|
||||
}
|
||||
table.button:active td a {
|
||||
color: #fff !important;
|
||||
}
|
||||
table.button:hover td {
|
||||
background: #2795b6 !important;
|
||||
}
|
||||
table.button:hover td a {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
table.button:active td a {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
table.button td a:visited {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
body {
|
||||
font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;
|
||||
}
|
||||
@media only screen and (max-width: 600px) {
|
||||
a[class="btn"] {
|
||||
display: block !important; margin-bottom: 10px !important; background-image: none !important; margin-right: 0 !important;
|
||||
table[class="body"] img {
|
||||
width: auto !important; height: auto !important;
|
||||
}
|
||||
div[class="column"] {
|
||||
width: auto !important; float: none !important;
|
||||
table[class="body"] center {
|
||||
min-width: 0 !important;
|
||||
}
|
||||
table.social div[class="column"] {
|
||||
width: auto !important;
|
||||
table[class="body"] .container {
|
||||
width: 95% !important;
|
||||
}
|
||||
table[class="body"] .row {
|
||||
width: 100% !important; display: block !important;
|
||||
}
|
||||
table[class="body"] .wrapper {
|
||||
display: block !important; padding-right: 0 !important;
|
||||
}
|
||||
table[class="body"] .columns {
|
||||
table-layout: fixed !important; float: none !important; width: 100% !important; padding-right: 0px !important; padding-left: 0px !important; display: block !important;
|
||||
}
|
||||
table[class="body"] table.columns td {
|
||||
width: 100% !important;
|
||||
}
|
||||
table[class="body"] .columns td.six {
|
||||
width: 50% !important;
|
||||
}
|
||||
table[class="body"] table.columns td.expander {
|
||||
width: 1px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<table class="body" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; border-collapse: collapse; border-spacing: 0; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; height: 100%; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="center" align="center" valign="top" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: center; vertical-align: top; word-break: break-word">
|
||||
<center style="min-width: 580px; width: 100%">
|
||||
|
||||
<!-- HEADER -->
|
||||
<table class="head-wrap" bgcolor="#666666" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
||||
<td class="header container" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto; padding: 0;">
|
||||
<table class="row header" style="background: #333; border-collapse: collapse; border-spacing: 0; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%" bgcolor="#333">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="center" align="center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: center; vertical-align: top; word-break: break-word" valign="top">
|
||||
<center style="min-width: 580px; width: 100%">
|
||||
|
||||
<div class="content" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; max-width: 600px; display: block; margin: 0 auto; padding: 15px;">
|
||||
<table style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td align="center" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><img src="http://grafana.org/assets/img/logo_transparent_200x75.png" alt="Grafana" style="width: 200px; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; max-width: 100%; margin: 0; padding: 0;" /></td>
|
||||
</tr></table></div>
|
||||
<table class="container" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: inherit; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
|
||||
</td>
|
||||
<td style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
||||
</tr></table><!-- /HEADER --><!-- BODY --><table class="body-wrap" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
||||
<td class="container" bgcolor="#FFFFFF" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto; padding: 0;">
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="six sub-columns center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; min-width: 0px; padding: 0px 10px 10px 0px; text-align: center; vertical-align: top; width: 50%; word-break: break-word" align="center" valign="top">
|
||||
<img src="http://docs.grafana.org/img/logo_transparent_200x75.png" style="-ms-interpolation-mode: bicubic; clear: both; display: inline; float: none; max-width: 100%; outline: none; text-decoration: none; width: 150px" align="none" />
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="content" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; max-width: 600px; display: block; margin: 0 auto; padding: 15px;">
|
||||
<table style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;">
|
||||
<td align="left" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;">
|
||||
<p style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-weight: normal; font-size: 14px; line-height: 1.6; margin: 25px 0 15px; font-weight:600;">Hi {{.Name}},</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p class="callout" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-weight: normal; font-size: 14px; line-height: 1.6; margin: 0 0 15px;">
|
||||
Thanks for signing up, we're happy to have you.
|
||||
</br></br>
|
||||
</td>
|
||||
</tr><tr style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td align="center" style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 25 0;">
|
||||
<table border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td align="center" style="-webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;" bgcolor="#13b2d4"><a href="{{.AppUrl}}" target="_blank" style="font-size: 16px; font-family: 'Open Sans', Helvetica, Arial, sans-serif; color: #ffffff; text-decoration: none; color: #ffffff; text-decoration: none; -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; padding: 12px 25px; border: 1px solid #13b2d4; display: inline-block; text-shadow: none;">Log into your Grafana server</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<!-- Callout Panel -->
|
||||
</tr>
|
||||
</table></div><!-- /content -->
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
<td style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
||||
</tr></table><!-- /BODY -->
|
||||
<table style="width: 100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<p style="font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; color: #999; font-weight: normal; font-size: 14px; line-height: 1.6; margin: 0 0 15px; padding: 15px;">© 2015 <a style="color:#13b2d4;text-decoration:none;" target="_blank" href="https://grafana.org">Grafana</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table><!-- /FOOTER -->
|
||||
<table class="container" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: inherit; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
{{Subject .Subject "Welcome to Grafana"}}
|
||||
|
||||
<table class="row" style="border-collapse: collapse; border-spacing: 0; display: block; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0px 0px 10px; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
<h3 style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 32px; font-weight: normal; line-height: 1.3; margin: 0; padding: 0; text-align: left; word-break: normal" align="left">Hi {{.Name}}</h3>
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="row" style="border-collapse: collapse; border-spacing: 0; display: block; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0px 0px 10px; text-align: center; vertical-align: top; word-break: break-word" align="center" valign="top">
|
||||
<p style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px; margin: 0 0 10px; padding: 0; text-align: left" align="left">
|
||||
If you are new to Grafana please read the <a href="http://docs.grafana.org/guides/gettingstarted/" style="color: #2ba6cb; text-decoration: none">Getting Started</a> guide.
|
||||
</p>
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
<table class="row footer" style="border-collapse: collapse; border-spacing: 0; display: block; margin-top: 20px; padding: 0px; position: relative; text-align: left; vertical-align: top; width: 100%">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td class="wrapper last" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 10px 0px 0px; position: relative; text-align: left; vertical-align: top; word-break: break-word" align="left" valign="top">
|
||||
<table class="twelve columns" style="border-collapse: collapse; border-spacing: 0; margin: 0 auto; padding: 0; text-align: left; vertical-align: top; width: 580px">
|
||||
<tr style="padding: 0; text-align: left; vertical-align: top" align="left">
|
||||
<td align="center" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0px 0px 10px; text-align: left; vertical-align: top; word-break: break-word" valign="top">
|
||||
<center style="min-width: 580px; width: 100%">
|
||||
<p style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px; margin: 0 0 10px; padding: 0; text-align: center" align="center">
|
||||
Sent by <a href="{{.AppUrl}}" style="color: #2ba6cb; text-decoration: none">Grafana v{{.BuildVersion}}</a>
|
||||
</p>
|
||||
</center>
|
||||
</td>
|
||||
<td class="expander" style="-moz-hyphens: auto; -webkit-font-smoothing: antialiased; -webkit-hyphens: auto; -webkit-text-size-adjust: none; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; hyphens: auto; line-height: 19px; margin: 0; padding: 0; text-align: left; vertical-align: top; visibility: hidden; width: 0px; word-break: break-word" align="left" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 173 KiB |
@@ -22,6 +22,7 @@ require.config({
|
||||
'angular-sanitize': '../vendor/angular-sanitize/angular-sanitize',
|
||||
angularMocks: '../vendor/angular-mocks/angular-mocks',
|
||||
'angular-dragdrop': '../vendor/angular-native-dragdrop/draganddrop',
|
||||
'angular-ui': '../vendor/angular-ui/angular-bootstrap',
|
||||
'angular-strap': '../vendor/angular-other/angular-strap',
|
||||
timepicker: '../vendor/angular-other/timepicker',
|
||||
datepicker: '../vendor/angular-other/datepicker',
|
||||
@@ -83,6 +84,7 @@ require.config({
|
||||
|
||||
'angular-route': ['angular'],
|
||||
'angular-sanitize': ['angular'],
|
||||
'angular-ui': ['angular'],
|
||||
'angular-dragdrop': ['jquery', 'angular'],
|
||||
'angular-mocks': ['angular'],
|
||||
'angular-strap': ['angular', 'bootstrap','timepicker', 'datepicker'],
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
define([
|
||||
'angular',
|
||||
'../vendor/angular-ui/tabs',
|
||||
], function() {
|
||||
});
|
||||
|
||||
Vendored
+293
@@ -0,0 +1,293 @@
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name ui.bootstrap.tabs
|
||||
*
|
||||
* @description
|
||||
* AngularJS version of the tabs directive.
|
||||
*/
|
||||
|
||||
angular.module('ui.bootstrap.tabs', [])
|
||||
|
||||
.controller('TabsetController', ['$scope', function TabsetCtrl($scope) {
|
||||
var ctrl = this,
|
||||
tabs = ctrl.tabs = $scope.tabs = [];
|
||||
|
||||
ctrl.select = function(selectedTab) {
|
||||
angular.forEach(tabs, function(tab) {
|
||||
if (tab.active && tab !== selectedTab) {
|
||||
tab.active = false;
|
||||
tab.onDeselect();
|
||||
}
|
||||
});
|
||||
selectedTab.active = true;
|
||||
selectedTab.onSelect();
|
||||
};
|
||||
|
||||
ctrl.addTab = function addTab(tab) {
|
||||
tabs.push(tab);
|
||||
// we can't run the select function on the first tab
|
||||
// since that would select it twice
|
||||
if (tabs.length === 1 && tab.active !== false) {
|
||||
tab.active = true;
|
||||
} else if (tab.active) {
|
||||
ctrl.select(tab);
|
||||
}
|
||||
else {
|
||||
tab.active = false;
|
||||
}
|
||||
};
|
||||
|
||||
ctrl.removeTab = function removeTab(tab) {
|
||||
var index = tabs.indexOf(tab);
|
||||
//Select a new tab if the tab to be removed is selected and not destroyed
|
||||
if (tab.active && tabs.length > 1 && !destroyed) {
|
||||
//If this is the last tab, select the previous tab. else, the next tab.
|
||||
var newActiveIndex = index == tabs.length - 1 ? index - 1 : index + 1;
|
||||
ctrl.select(tabs[newActiveIndex]);
|
||||
}
|
||||
tabs.splice(index, 1);
|
||||
};
|
||||
|
||||
var destroyed;
|
||||
$scope.$on('$destroy', function() {
|
||||
destroyed = true;
|
||||
});
|
||||
}])
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ui.bootstrap.tabs.directive:tabset
|
||||
* @restrict EA
|
||||
*
|
||||
* @description
|
||||
* Tabset is the outer container for the tabs directive
|
||||
*
|
||||
* @param {boolean=} vertical Whether or not to use vertical styling for the tabs.
|
||||
* @param {boolean=} justified Whether or not to use justified styling for the tabs.
|
||||
*
|
||||
* @example
|
||||
<example module="ui.bootstrap">
|
||||
<file name="index.html">
|
||||
<tabset>
|
||||
<tab heading="Tab 1"><b>First</b> Content!</tab>
|
||||
<tab heading="Tab 2"><i>Second</i> Content!</tab>
|
||||
</tabset>
|
||||
<hr />
|
||||
<tabset vertical="true">
|
||||
<tab heading="Vertical Tab 1"><b>First</b> Vertical Content!</tab>
|
||||
<tab heading="Vertical Tab 2"><i>Second</i> Vertical Content!</tab>
|
||||
</tabset>
|
||||
<tabset justified="true">
|
||||
<tab heading="Justified Tab 1"><b>First</b> Justified Content!</tab>
|
||||
<tab heading="Justified Tab 2"><i>Second</i> Justified Content!</tab>
|
||||
</tabset>
|
||||
</file>
|
||||
</example>
|
||||
*/
|
||||
.directive('tabset', function() {
|
||||
return {
|
||||
restrict: 'EA',
|
||||
transclude: true,
|
||||
replace: true,
|
||||
scope: {
|
||||
type: '@'
|
||||
},
|
||||
controller: 'TabsetController',
|
||||
templateUrl: 'app/partials/bootstrap/tabset.html',
|
||||
link: function(scope, element, attrs) {
|
||||
scope.vertical = angular.isDefined(attrs.vertical) ? scope.$parent.$eval(attrs.vertical) : false;
|
||||
scope.justified = angular.isDefined(attrs.justified) ? scope.$parent.$eval(attrs.justified) : false;
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ui.bootstrap.tabs.directive:tab
|
||||
* @restrict EA
|
||||
*
|
||||
* @param {string=} heading The visible heading, or title, of the tab. Set HTML headings with {@link ui.bootstrap.tabs.directive:tabHeading tabHeading}.
|
||||
* @param {string=} select An expression to evaluate when the tab is selected.
|
||||
* @param {boolean=} active A binding, telling whether or not this tab is selected.
|
||||
* @param {boolean=} disabled A binding, telling whether or not this tab is disabled.
|
||||
*
|
||||
* @description
|
||||
* Creates a tab with a heading and content. Must be placed within a {@link ui.bootstrap.tabs.directive:tabset tabset}.
|
||||
*
|
||||
* @example
|
||||
<example module="ui.bootstrap">
|
||||
<file name="index.html">
|
||||
<div ng-controller="TabsDemoCtrl">
|
||||
<button class="btn btn-small" ng-click="items[0].active = true">
|
||||
Select item 1, using active binding
|
||||
</button>
|
||||
<button class="btn btn-small" ng-click="items[1].disabled = !items[1].disabled">
|
||||
Enable/disable item 2, using disabled binding
|
||||
</button>
|
||||
<br />
|
||||
<tabset>
|
||||
<tab heading="Tab 1">First Tab</tab>
|
||||
<tab select="alertMe()">
|
||||
<tab-heading><i class="icon-bell"></i> Alert me!</tab-heading>
|
||||
Second Tab, with alert callback and html heading!
|
||||
</tab>
|
||||
<tab ng-repeat="item in items"
|
||||
heading="{{item.title}}"
|
||||
disabled="item.disabled"
|
||||
active="item.active">
|
||||
{{item.content}}
|
||||
</tab>
|
||||
</tabset>
|
||||
</div>
|
||||
</file>
|
||||
<file name="script.js">
|
||||
function TabsDemoCtrl($scope) {
|
||||
$scope.items = [
|
||||
{ title:"Dynamic Title 1", content:"Dynamic Item 0" },
|
||||
{ title:"Dynamic Title 2", content:"Dynamic Item 1", disabled: true }
|
||||
];
|
||||
|
||||
$scope.alertMe = function() {
|
||||
setTimeout(function() {
|
||||
alert("You've selected the alert tab!");
|
||||
});
|
||||
};
|
||||
};
|
||||
</file>
|
||||
</example>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ui.bootstrap.tabs.directive:tabHeading
|
||||
* @restrict EA
|
||||
*
|
||||
* @description
|
||||
* Creates an HTML heading for a {@link ui.bootstrap.tabs.directive:tab tab}. Must be placed as a child of a tab element.
|
||||
*
|
||||
* @example
|
||||
<example module="ui.bootstrap">
|
||||
<file name="index.html">
|
||||
<tabset>
|
||||
<tab>
|
||||
<tab-heading><b>HTML</b> in my titles?!</tab-heading>
|
||||
And some content, too!
|
||||
</tab>
|
||||
<tab>
|
||||
<tab-heading><i class="icon-heart"></i> Icon heading?!?</tab-heading>
|
||||
That's right.
|
||||
</tab>
|
||||
</tabset>
|
||||
</file>
|
||||
</example>
|
||||
*/
|
||||
.directive('tab', ['$parse', '$log', function($parse, $log) {
|
||||
return {
|
||||
require: '^tabset',
|
||||
restrict: 'EA',
|
||||
replace: true,
|
||||
templateUrl: 'app/partials/bootstrap/tab.html',
|
||||
transclude: true,
|
||||
scope: {
|
||||
active: '=?',
|
||||
heading: '@',
|
||||
onSelect: '&select', //This callback is called in contentHeadingTransclude
|
||||
//once it inserts the tab's content into the dom
|
||||
onDeselect: '&deselect'
|
||||
},
|
||||
controller: function() {
|
||||
//Empty controller so other directives can require being 'under' a tab
|
||||
},
|
||||
compile: function(elm, attrs, transclude) {
|
||||
return function postLink(scope, elm, attrs, tabsetCtrl) {
|
||||
scope.$watch('active', function(active) {
|
||||
if (active) {
|
||||
tabsetCtrl.select(scope);
|
||||
}
|
||||
});
|
||||
|
||||
scope.disabled = false;
|
||||
if ( attrs.disable ) {
|
||||
scope.$parent.$watch($parse(attrs.disable), function(value) {
|
||||
scope.disabled = !! value;
|
||||
});
|
||||
}
|
||||
|
||||
// Deprecation support of "disabled" parameter
|
||||
// fix(tab): IE9 disabled attr renders grey text on enabled tab #2677
|
||||
// This code is duplicated from the lines above to make it easy to remove once
|
||||
// the feature has been completely deprecated
|
||||
if ( attrs.disabled ) {
|
||||
$log.warn('Use of "disabled" attribute has been deprecated, please use "disable"');
|
||||
scope.$parent.$watch($parse(attrs.disabled), function(value) {
|
||||
scope.disabled = !! value;
|
||||
});
|
||||
}
|
||||
|
||||
scope.select = function() {
|
||||
if ( !scope.disabled ) {
|
||||
scope.active = true;
|
||||
}
|
||||
};
|
||||
|
||||
tabsetCtrl.addTab(scope);
|
||||
scope.$on('$destroy', function() {
|
||||
tabsetCtrl.removeTab(scope);
|
||||
});
|
||||
|
||||
//We need to transclude later, once the content container is ready.
|
||||
//when this link happens, we're inside a tab heading.
|
||||
scope.$transcludeFn = transclude;
|
||||
};
|
||||
}
|
||||
};
|
||||
}])
|
||||
|
||||
.directive('tabHeadingTransclude', [function() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: '^tab',
|
||||
link: function(scope, elm, attrs, tabCtrl) {
|
||||
scope.$watch('headingElement', function updateHeadingElement(heading) {
|
||||
if (heading) {
|
||||
elm.html('');
|
||||
elm.append(heading);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}])
|
||||
|
||||
.directive('tabContentTransclude', function() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: '^tabset',
|
||||
link: function(scope, elm, attrs) {
|
||||
var tab = scope.$eval(attrs.tabContentTransclude);
|
||||
|
||||
//Now our tab is ready to be transcluded: both the tab heading area
|
||||
//and the tab content area are loaded. Transclude 'em both.
|
||||
tab.$transcludeFn(tab.$parent, function(contents) {
|
||||
angular.forEach(contents, function(node) {
|
||||
if (isTabHeading(node)) {
|
||||
//Let tabHeadingTransclude know.
|
||||
tab.headingElement = node;
|
||||
} else {
|
||||
elm.append(node);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
function isTabHeading(node) {
|
||||
return node.tagName && (
|
||||
node.hasAttribute('tab-heading') ||
|
||||
node.hasAttribute('data-tab-heading') ||
|
||||
node.tagName.toLowerCase() === 'tab-heading' ||
|
||||
node.tagName.toLowerCase() === 'data-tab-heading'
|
||||
);
|
||||
}
|
||||
})
|
||||
|
||||
;
|
||||
-1
@@ -22,7 +22,6 @@
|
||||
|
||||
// Base CSS
|
||||
@import "type.less";
|
||||
@import "code.less";
|
||||
@import "forms.less";
|
||||
@import "tables.less";
|
||||
|
||||
|
||||
-246
@@ -1,247 +1 @@
|
||||
//
|
||||
// Typography
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
// Body text
|
||||
// -------------------------
|
||||
|
||||
p {
|
||||
margin: 0 0 @baseLineHeight / 2;
|
||||
}
|
||||
.lead {
|
||||
margin-bottom: @baseLineHeight;
|
||||
font-size: @baseFontSize * 1.5;
|
||||
font-weight: 200;
|
||||
line-height: @baseLineHeight * 1.5;
|
||||
}
|
||||
|
||||
|
||||
// Emphasis & misc
|
||||
// -------------------------
|
||||
|
||||
// Ex: 14px base font * 85% = about 12px
|
||||
small { font-size: 85%; }
|
||||
|
||||
strong { font-weight: bold; }
|
||||
em { font-style: italic; }
|
||||
cite { font-style: normal; }
|
||||
|
||||
// Utility classes
|
||||
.muted { color: @grayLight; }
|
||||
a.muted:hover,
|
||||
a.muted:focus { color: darken(@grayLight, 10%); }
|
||||
|
||||
.text-warning { color: @warningText; }
|
||||
a.text-warning:hover,
|
||||
a.text-warning:focus { color: darken(@warningText, 10%); }
|
||||
|
||||
.text-error { color: @errorText; }
|
||||
a.text-error:hover,
|
||||
a.text-error:focus { color: darken(@errorText, 10%); }
|
||||
|
||||
.text-info { color: @infoText; }
|
||||
a.text-info:hover,
|
||||
a.text-info:focus { color: darken(@infoText, 10%); }
|
||||
|
||||
.text-success { color: @successText; }
|
||||
a.text-success:hover,
|
||||
a.text-success:focus { color: darken(@successText, 10%); }
|
||||
|
||||
.text-left { text-align: left; }
|
||||
.text-right { text-align: right; }
|
||||
.text-center { text-align: center; }
|
||||
|
||||
|
||||
// Headings
|
||||
// -------------------------
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: (@baseLineHeight / 2) 0;
|
||||
font-family: @headingsFontFamily;
|
||||
font-weight: @headingsFontWeight;
|
||||
line-height: @baseLineHeight;
|
||||
color: @headingsColor;
|
||||
text-rendering: optimizelegibility; // Fix the character spacing for headings
|
||||
small {
|
||||
font-weight: normal;
|
||||
line-height: 1;
|
||||
color: @grayLight;
|
||||
}
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3 { line-height: @baseLineHeight * 2; }
|
||||
|
||||
h1 { font-size: @baseFontSize * 2.75; } // ~38px
|
||||
h2 { font-size: @baseFontSize * 2.25; } // ~32px
|
||||
h3 { font-size: @baseFontSize * 1.75; } // ~24px
|
||||
h4 { font-size: @baseFontSize * 1.25; } // ~18px
|
||||
h5 { font-size: @baseFontSize; }
|
||||
h6 { font-size: @baseFontSize * 0.85; } // ~12px
|
||||
|
||||
h1 small { font-size: @baseFontSize * 1.75; } // ~24px
|
||||
h2 small { font-size: @baseFontSize * 1.25; } // ~18px
|
||||
h3 small { font-size: @baseFontSize; }
|
||||
h4 small { font-size: @baseFontSize; }
|
||||
|
||||
|
||||
// Page header
|
||||
// -------------------------
|
||||
|
||||
.page-header {
|
||||
padding-bottom: (@baseLineHeight / 2) - 1;
|
||||
margin: @baseLineHeight 0 (@baseLineHeight * 1.5);
|
||||
border-bottom: 1px solid @grayLighter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Lists
|
||||
// --------------------------------------------------
|
||||
|
||||
// Unordered and Ordered lists
|
||||
ul, ol {
|
||||
padding: 0;
|
||||
margin: 0 0 @baseLineHeight / 2 25px;
|
||||
}
|
||||
ul ul,
|
||||
ul ol,
|
||||
ol ol,
|
||||
ol ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
li {
|
||||
line-height: @baseLineHeight;
|
||||
}
|
||||
|
||||
// Remove default list styles
|
||||
ul.unstyled,
|
||||
ol.unstyled {
|
||||
margin-left: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
// Single-line list items
|
||||
ul.inline,
|
||||
ol.inline {
|
||||
margin-left: 0;
|
||||
list-style: none;
|
||||
> li {
|
||||
display: inline-block;
|
||||
.ie7-inline-block();
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
// Description Lists
|
||||
dl {
|
||||
margin-bottom: @baseLineHeight;
|
||||
}
|
||||
dt,
|
||||
dd {
|
||||
line-height: @baseLineHeight;
|
||||
}
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
dd {
|
||||
margin-left: @baseLineHeight / 2;
|
||||
}
|
||||
// Horizontal layout (like forms)
|
||||
.dl-horizontal {
|
||||
.clearfix(); // Ensure dl clears floats if empty dd elements present
|
||||
dt {
|
||||
float: left;
|
||||
width: @horizontalComponentOffset - 20;
|
||||
clear: left;
|
||||
text-align: right;
|
||||
.text-overflow();
|
||||
}
|
||||
dd {
|
||||
margin-left: @horizontalComponentOffset;
|
||||
}
|
||||
}
|
||||
|
||||
// MISC
|
||||
// ----
|
||||
|
||||
// Horizontal rules
|
||||
hr {
|
||||
margin: @baseLineHeight 0;
|
||||
border: 0;
|
||||
border-top: 1px solid @hrBorder;
|
||||
border-bottom: 1px solid @white;
|
||||
}
|
||||
|
||||
// Abbreviations and acronyms
|
||||
abbr[title],
|
||||
// Added data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257
|
||||
abbr[data-original-title] {
|
||||
cursor: help;
|
||||
border-bottom: 1px dotted @grayLight;
|
||||
}
|
||||
abbr.initialism {
|
||||
font-size: 90%;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
// Blockquotes
|
||||
blockquote {
|
||||
padding: 0 0 0 15px;
|
||||
margin: 0 0 @baseLineHeight;
|
||||
border-left: 5px solid @grayLighter;
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
font-size: @baseFontSize * 1.25;
|
||||
font-weight: 300;
|
||||
line-height: 1.25;
|
||||
}
|
||||
small {
|
||||
display: block;
|
||||
line-height: @baseLineHeight;
|
||||
color: @grayLight;
|
||||
&:before {
|
||||
content: '\2014 \00A0';
|
||||
}
|
||||
}
|
||||
|
||||
// Float right with text-align: right
|
||||
&.pull-right {
|
||||
float: right;
|
||||
padding-right: 15px;
|
||||
padding-left: 0;
|
||||
border-right: 5px solid @grayLighter;
|
||||
border-left: 0;
|
||||
p,
|
||||
small {
|
||||
text-align: right;
|
||||
}
|
||||
small {
|
||||
&:before {
|
||||
content: '';
|
||||
}
|
||||
&:after {
|
||||
content: '\00A0 \2014';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Quotes
|
||||
q:before,
|
||||
q:after,
|
||||
blockquote:before,
|
||||
blockquote:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
// Addresses
|
||||
address {
|
||||
display: block;
|
||||
margin-bottom: @baseLineHeight;
|
||||
font-style: normal;
|
||||
line-height: @baseLineHeight;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user