mirror of
https://github.com/grafana/grafana.git
synced 2024-12-28 18:01:40 -06:00
feat(invite): progress on invite feature, #2353
This commit is contained in:
parent
93b8287d23
commit
775e044e69
@ -22,7 +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", Index)
|
||||
r.Get("/invite/:code", Index)
|
||||
|
||||
// authed views
|
||||
r.Get("/profile/", reqSignedIn, Index)
|
||||
|
@ -10,9 +10,10 @@ type AddInviteForm struct {
|
||||
}
|
||||
|
||||
type InviteInfo struct {
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
InvitedBy string `json:"invitedBy"`
|
||||
}
|
||||
|
||||
type CompleteInviteForm struct {
|
||||
|
@ -78,7 +78,7 @@ func AddOrgInvite(c *middleware.Context, inviteDto dtos.AddInviteForm) Response
|
||||
"OrgName": c.OrgName,
|
||||
"Email": c.Email,
|
||||
"LinkUrl": setting.ToAbsUrl("invite/" + cmd.Code),
|
||||
"InvitedBy": util.StringsFallback2(c.Name, c.Email),
|
||||
"InvitedBy": util.StringsFallback3(c.Name, c.Email, c.Login),
|
||||
},
|
||||
}
|
||||
|
||||
@ -114,13 +114,14 @@ func GetInviteInfoByCode(c *middleware.Context) Response {
|
||||
return ApiError(500, "Failed to get invite", err)
|
||||
}
|
||||
|
||||
info := dtos.InviteInfo{
|
||||
Email: query.Result.Email,
|
||||
Name: query.Result.Name,
|
||||
Username: query.Result.Email,
|
||||
}
|
||||
invite := query.Result
|
||||
|
||||
return Json(200, &info)
|
||||
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 {
|
||||
|
@ -70,18 +70,21 @@ type GetTempUsersForOrgQuery struct {
|
||||
type GetTempUserByCodeQuery struct {
|
||||
Code string
|
||||
|
||||
Result *TempUser
|
||||
Result *TempUserDTO
|
||||
}
|
||||
|
||||
type TempUserDTO struct {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Role string `json:"role"`
|
||||
InvitedBy string `json:"invitedBy"`
|
||||
Code string `json:"code"`
|
||||
Url string `json:"url"`
|
||||
EmailSent bool `json:"emailSent"`
|
||||
EmailSentOn time.Time `json:"emailSentOn"`
|
||||
Created time.Time `json:"createdOn"`
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Role string `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"`
|
||||
}
|
||||
|
@ -56,10 +56,13 @@ func GetTempUsersForOrg(query *m.GetTempUsersForOrgQuery) error {
|
||||
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
|
||||
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`
|
||||
@ -71,8 +74,26 @@ func GetTempUsersForOrg(query *m.GetTempUsersForOrgQuery) error {
|
||||
}
|
||||
|
||||
func GetTempUserByCode(query *m.GetTempUserByCodeQuery) error {
|
||||
var user m.TempUser
|
||||
has, err := x.Table("temp_user").Where("code=?", query.Code).Get(&user)
|
||||
var rawSql = `SELECT
|
||||
tu.id as 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
|
||||
@ -80,6 +101,6 @@ func GetTempUserByCode(query *m.GetTempUserByCodeQuery) error {
|
||||
return m.ErrTempUserNotFound
|
||||
}
|
||||
|
||||
query.Result = &user
|
||||
query.Result = &tempUser
|
||||
return err
|
||||
}
|
||||
|
@ -32,6 +32,14 @@ func TestTempUserCommandsAndQueries(t *testing.T) {
|
||||
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)
|
||||
|
@ -6,3 +6,13 @@ func StringsFallback2(val1 string, val2 string) string {
|
||||
}
|
||||
return val2
|
||||
}
|
||||
|
||||
func StringsFallback3(val1 string, val2 string, val3 string) string {
|
||||
if val1 != "" {
|
||||
return val1
|
||||
}
|
||||
if val2 != "" {
|
||||
return val2
|
||||
}
|
||||
return val3
|
||||
}
|
||||
|
@ -20,7 +20,8 @@ function (angular, config) {
|
||||
$scope.formModel.username = invite.email;
|
||||
$scope.formModel.inviteCode = $routeParams.code;
|
||||
|
||||
$scope.greeting = invite.name || invite.email;
|
||||
$scope.greeting = invite.name || invite.email || invite.username;
|
||||
$scope.invitedBy = invite.invitedBy;
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -14,8 +14,8 @@
|
||||
Hello {{greeting}}.
|
||||
</h3>
|
||||
|
||||
<div class="long-tag modal-tagline">
|
||||
<span class="body-copy-emphasis">{{.InvitedBy}}</span> has invited you to join the <span class="highlight-word">{{contextSrv.user.orgName}}</span> organization in Grafana.</br>Please complete the following to accept your invitation and continue:
|
||||
<div class="modal-tagline">
|
||||
<em>{{invitedBy}}</em> has invited you to join the <span class="highlight-word">{{contextSrv.user.orgName}}</span> organization in Grafana.</br>Please complete the following to accept your invitation and continue:
|
||||
</div>
|
||||
|
||||
<form name="inviteForm" class="login-form">
|
||||
@ -65,17 +65,6 @@
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 128px">
|
||||
Confirm Password
|
||||
</li>
|
||||
<li>
|
||||
<input type="password" name="confirmPassword" class="tight-form-input last" required ng-model="formModel.confirmPassword" id="confirmPassword" style="width: 253px" placeholder="confirm password">
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-left: 147px; width: 254px;">
|
||||
|
@ -1,3 +1,4 @@
|
||||
@import "type.less";
|
||||
@import "login.less";
|
||||
@import "submenu.less";
|
||||
@import "graph.less";
|
||||
@ -277,11 +278,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.long-tag {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.confirm-modal {
|
||||
max-width: 500px;
|
||||
|
||||
@ -371,7 +367,7 @@
|
||||
}
|
||||
|
||||
.body-copy-emphasis {
|
||||
color: @headingsColor;
|
||||
color: @headingsColor;
|
||||
}
|
||||
|
||||
.signup-page-container {
|
||||
|
247
public/css/less/type.less
Normal file
247
public/css/less/type.less
Normal file
@ -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;
|
||||
}
|
1
public/vendor/bootstrap/less/bootstrap.less
vendored
1
public/vendor/bootstrap/less/bootstrap.less
vendored
@ -22,7 +22,6 @@
|
||||
|
||||
// Base CSS
|
||||
@import "type.less";
|
||||
@import "code.less";
|
||||
@import "forms.less";
|
||||
@import "tables.less";
|
||||
|
||||
|
246
public/vendor/bootstrap/less/type.less
vendored
246
public/vendor/bootstrap/less/type.less
vendored
@ -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.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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user