forked from gitea/gitea
		
	#1193 Make organization emails non-mandatory
This commit is contained in:
		
							parent
							
								
									aa67de910a
								
							
						
					
					
						commit
						80701d45bb
					
				| @ -630,7 +630,6 @@ release.tag_name_already_exist = Release with this tag name has already existed. | ||||
| [org] | ||||
| org_name_holder = Organization Name | ||||
| org_name_helper = Great organization names are short and memorable. | ||||
| org_email_helper = Organization's E-mail receives all notifications and confirmations. | ||||
| create_org = Create Organization | ||||
| repo_updated = Updated | ||||
| people = People | ||||
|  | ||||
| @ -9,8 +9,6 @@ import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/gogits/gogs/modules/base" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| @ -93,17 +91,6 @@ func (org *User) RemoveOrgRepo(repoID int64) error { | ||||
| 	return org.removeOrgRepo(x, repoID) | ||||
| } | ||||
| 
 | ||||
| // IsOrgEmailUsed returns true if the e-mail has been used in organization account. | ||||
| func IsOrgEmailUsed(email string) (bool, error) { | ||||
| 	if len(email) == 0 { | ||||
| 		return false, nil | ||||
| 	} | ||||
| 	return x.Get(&User{ | ||||
| 		Email: email, | ||||
| 		Type:  ORGANIZATION, | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // CreateOrganization creates record of a new organization. | ||||
| func CreateOrganization(org, owner *User) (err error) { | ||||
| 	if err = IsUsableName(org.Name); err != nil { | ||||
| @ -117,18 +104,9 @@ func CreateOrganization(org, owner *User) (err error) { | ||||
| 		return ErrUserAlreadyExist{org.Name} | ||||
| 	} | ||||
| 
 | ||||
| 	isExist, err = IsOrgEmailUsed(org.Email) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} else if isExist { | ||||
| 		return ErrEmailAlreadyUsed{org.Email} | ||||
| 	} | ||||
| 
 | ||||
| 	org.LowerName = strings.ToLower(org.Name) | ||||
| 	org.FullName = org.Name | ||||
| 	org.Avatar = base.EncodeMd5(org.Email) | ||||
| 	org.AvatarEmail = org.Email | ||||
| 	// No password for organization. | ||||
| 	org.UseCustomAvatar = true | ||||
| 	org.NumTeams = 1 | ||||
| 	org.NumMembers = 1 | ||||
| 
 | ||||
| @ -141,6 +119,17 @@ func CreateOrganization(org, owner *User) (err error) { | ||||
| 	if _, err = sess.Insert(org); err != nil { | ||||
| 		return fmt.Errorf("insert organization: %v", err) | ||||
| 	} | ||||
| 	org.GenerateRandomAvatar() | ||||
| 
 | ||||
| 	// Add initial creator to organization and owner team. | ||||
| 	if _, err = sess.Insert(&OrgUser{ | ||||
| 		Uid:      owner.Id, | ||||
| 		OrgID:    org.Id, | ||||
| 		IsOwner:  true, | ||||
| 		NumTeams: 1, | ||||
| 	}); err != nil { | ||||
| 		return fmt.Errorf("insert org-user relation: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Create default owner team. | ||||
| 	t := &Team{ | ||||
| @ -154,23 +143,11 @@ func CreateOrganization(org, owner *User) (err error) { | ||||
| 		return fmt.Errorf("insert owner team: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Add initial creator to organization and owner team. | ||||
| 	ou := &OrgUser{ | ||||
| 		Uid:      owner.Id, | ||||
| 		OrgID:    org.Id, | ||||
| 		IsOwner:  true, | ||||
| 		NumTeams: 1, | ||||
| 	} | ||||
| 	if _, err = sess.Insert(ou); err != nil { | ||||
| 		return fmt.Errorf("insert org-user relation: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	tu := &TeamUser{ | ||||
| 	if _, err = sess.Insert(&TeamUser{ | ||||
| 		Uid:    owner.Id, | ||||
| 		OrgID:  org.Id, | ||||
| 		TeamID: t.ID, | ||||
| 	} | ||||
| 	if _, err = sess.Insert(tu); err != nil { | ||||
| 	}); err != nil { | ||||
| 		return fmt.Errorf("insert team-user relation: %v", err) | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -55,12 +55,12 @@ type User struct { | ||||
| 	Name      string `xorm:"UNIQUE NOT NULL"` | ||||
| 	FullName  string | ||||
| 	// Email is the primary email address (to be used for communication). | ||||
| 	Email       string `xorm:"UNIQUE(s) NOT NULL"` | ||||
| 	Email       string `xorm:"NOT NULL"` | ||||
| 	Passwd      string `xorm:"NOT NULL"` | ||||
| 	LoginType   LoginType | ||||
| 	LoginSource int64 `xorm:"NOT NULL DEFAULT 0"` | ||||
| 	LoginName   string | ||||
| 	Type        UserType      `xorm:"UNIQUE(s)"` | ||||
| 	Type        UserType | ||||
| 	Orgs        []*User       `xorm:"-"` | ||||
| 	Repos       []*Repository `xorm:"-"` | ||||
| 	Location    string | ||||
| @ -132,42 +132,56 @@ func (u *User) HomeLink() string { | ||||
| 	return setting.AppSubUrl + "/" + u.Name | ||||
| } | ||||
| 
 | ||||
| // CustomAvatarPath returns user custom avatar file path. | ||||
| func (u *User) CustomAvatarPath() string { | ||||
| 	return filepath.Join(setting.AvatarUploadPath, com.ToStr(u.Id)) | ||||
| } | ||||
| 
 | ||||
| // GenerateRandomAvatar generates a random avatar for user. | ||||
| func (u *User) GenerateRandomAvatar() error { | ||||
| 	seed := u.Email | ||||
| 	if len(seed) == 0 { | ||||
| 		seed = u.Name | ||||
| 	} | ||||
| 
 | ||||
| 	img, err := avatar.RandomImage([]byte(seed)) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("RandomImage: %v", err) | ||||
| 	} | ||||
| 	if err = os.MkdirAll(path.Dir(u.CustomAvatarPath()), os.ModePerm); err != nil { | ||||
| 		return fmt.Errorf("MkdirAll: %v", err) | ||||
| 	} | ||||
| 	fw, err := os.Create(u.CustomAvatarPath()) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("Create: %v", err) | ||||
| 	} | ||||
| 	defer fw.Close() | ||||
| 
 | ||||
| 	if err = jpeg.Encode(fw, img, nil); err != nil { | ||||
| 		return fmt.Errorf("Encode: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	log.Info("New random avatar created: %d", u.Id) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (u *User) RelAvatarLink() string { | ||||
| 	defaultImgUrl := "/img/avatar_default.jpg" | ||||
| 	if u.Id == -1 { | ||||
| 		return defaultImgUrl | ||||
| 	} | ||||
| 
 | ||||
| 	imgPath := path.Join(setting.AvatarUploadPath, com.ToStr(u.Id)) | ||||
| 	switch { | ||||
| 	case u.UseCustomAvatar: | ||||
| 		if !com.IsExist(imgPath) { | ||||
| 		if !com.IsExist(u.CustomAvatarPath()) { | ||||
| 			return defaultImgUrl | ||||
| 		} | ||||
| 		return "/avatars/" + com.ToStr(u.Id) | ||||
| 	case setting.DisableGravatar, setting.OfflineMode: | ||||
| 		if !com.IsExist(imgPath) { | ||||
| 			img, err := avatar.RandomImage([]byte(u.Email)) | ||||
| 			if err != nil { | ||||
| 				log.Error(3, "RandomImage: %v", err) | ||||
| 				return defaultImgUrl | ||||
| 		if !com.IsExist(u.CustomAvatarPath()) { | ||||
| 			if err := u.GenerateRandomAvatar(); err != nil { | ||||
| 				log.Error(3, "GenerateRandomAvatar: %v", err) | ||||
| 			} | ||||
| 			if err = os.MkdirAll(path.Dir(imgPath), os.ModePerm); err != nil { | ||||
| 				log.Error(3, "MkdirAll: %v", err) | ||||
| 				return defaultImgUrl | ||||
| 			} | ||||
| 			fw, err := os.Create(imgPath) | ||||
| 			if err != nil { | ||||
| 				log.Error(3, "Create: %v", err) | ||||
| 				return defaultImgUrl | ||||
| 			} | ||||
| 			defer fw.Close() | ||||
| 
 | ||||
| 			if err = jpeg.Encode(fw, img, nil); err != nil { | ||||
| 				log.Error(3, "Encode: %v", err) | ||||
| 				return defaultImgUrl | ||||
| 			} | ||||
| 			log.Info("New random avatar created: %d", u.Id) | ||||
| 		} | ||||
| 
 | ||||
| 		return "/avatars/" + com.ToStr(u.Id) | ||||
| @ -208,11 +222,6 @@ func (u *User) ValidatePassword(passwd string) bool { | ||||
| 	return u.Passwd == newUser.Passwd | ||||
| } | ||||
| 
 | ||||
| // CustomAvatarPath returns user custom avatar file path. | ||||
| func (u *User) CustomAvatarPath() string { | ||||
| 	return filepath.Join(setting.AvatarUploadPath, com.ToStr(u.Id)) | ||||
| } | ||||
| 
 | ||||
| // UploadAvatar saves custom avatar for user. | ||||
| // FIXME: split uploads to different subdirs in case we have massive users. | ||||
| func (u *User) UploadAvatar(data []byte) error { | ||||
| @ -494,12 +503,20 @@ func ChangeUserName(u *User, newUserName string) (err error) { | ||||
| } | ||||
| 
 | ||||
| func updateUser(e Engine, u *User) error { | ||||
| 	u.Email = strings.ToLower(u.Email) | ||||
| 	has, err := e.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} else if has { | ||||
| 		return ErrEmailAlreadyUsed{u.Email} | ||||
| 	// Organization does not need e-mail. | ||||
| 	if !u.IsOrganization() { | ||||
| 		u.Email = strings.ToLower(u.Email) | ||||
| 		has, err := e.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User)) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} else if has { | ||||
| 			return ErrEmailAlreadyUsed{u.Email} | ||||
| 		} | ||||
| 
 | ||||
| 		if len(u.AvatarEmail) == 0 { | ||||
| 			u.AvatarEmail = u.Email | ||||
| 		} | ||||
| 		u.Avatar = avatar.HashEmail(u.AvatarEmail) | ||||
| 	} | ||||
| 
 | ||||
| 	u.LowerName = strings.ToLower(u.Name) | ||||
| @ -514,13 +531,8 @@ func updateUser(e Engine, u *User) error { | ||||
| 		u.Description = u.Description[:255] | ||||
| 	} | ||||
| 
 | ||||
| 	if u.AvatarEmail == "" { | ||||
| 		u.AvatarEmail = u.Email | ||||
| 	} | ||||
| 	u.Avatar = avatar.HashEmail(u.AvatarEmail) | ||||
| 
 | ||||
| 	u.FullName = base.Sanitizer.Sanitize(u.FullName) | ||||
| 	_, err = e.Id(u.Id).AllCols().Update(u) | ||||
| 	_, err := e.Id(u.Id).AllCols().Update(u) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -17,8 +17,7 @@ import ( | ||||
| //         \/     /_____/     \/     \/         \/     \/                    \/ | ||||
| 
 | ||||
| type CreateOrgForm struct { | ||||
| 	OrgName string `form:"org_name" binding:"Required;AlphaDashDot;MaxSize(30)"` | ||||
| 	Email   string `form:"email" binding:"Required;Email;MaxSize(50)"` | ||||
| 	OrgName string `binding:"Required;AlphaDashDot;MaxSize(30)"` | ||||
| } | ||||
| 
 | ||||
| func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
| @ -28,11 +27,9 @@ func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs binding.Errors) bind | ||||
| type UpdateOrgSettingForm struct { | ||||
| 	OrgUserName string `form:"uname" binding:"Required;AlphaDashDot;MaxSize(30)" locale:"org.org_name_holder"` | ||||
| 	OrgFullName string `form:"fullname" binding:"MaxSize(100)"` | ||||
| 	Email       string `form:"email" binding:"Required;Email;MaxSize(50)"` | ||||
| 	Description string `form:"desc" binding:"MaxSize(255)"` | ||||
| 	Website     string `form:"website" binding:"Url;MaxSize(100)"` | ||||
| 	Location    string `form:"location" binding:"MaxSize(50)"` | ||||
| 	Avatar      string `form:"avatar" binding:"Required;Email;MaxSize(50)"` | ||||
| } | ||||
| 
 | ||||
| func (f *UpdateOrgSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
|  | ||||
							
								
								
									
										2
									
								
								public/css/gogs.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								public/css/gogs.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -17,28 +17,41 @@ | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @create-page-form-input-padding: 250px !important; | ||||
| #create-page-form { | ||||
| 	form { | ||||
| 		margin: auto; | ||||
| 		width: 800px!important; | ||||
| 		.ui.message { | ||||
| 			text-align: center; | ||||
| 		} | ||||
| 		.header { | ||||
| 			padding-left: @create-page-form-input-padding+30px; | ||||
| 		} | ||||
| 		.inline.field > label { | ||||
| 			text-align: right; | ||||
| 			width: @create-page-form-input-padding; | ||||
| 			word-wrap: break-word; | ||||
| 		} | ||||
| 		.help { | ||||
| 			margin-left: @create-page-form-input-padding+15px; | ||||
| 		} | ||||
| 		.optional .title { | ||||
| 			margin-left: @create-page-form-input-padding; | ||||
| 		} | ||||
| 		input, | ||||
| 		textarea { | ||||
| 			width: 50%!important; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| .repository { | ||||
| 	@input-padding: 250px !important; | ||||
| 	&.new.repo, | ||||
| 	&.new.migrate, | ||||
| 	&.new.fork { | ||||
| 		#create-page-form; | ||||
| 		form { | ||||
| 			margin: auto; | ||||
| 			width: 800px!important; | ||||
| 			.ui.message { | ||||
| 				text-align: center; | ||||
| 			} | ||||
| 			.header { | ||||
| 				padding-left: @input-padding+30px; | ||||
| 			} | ||||
| 			.inline.field > label { | ||||
| 				text-align: right; | ||||
| 				width: @input-padding; | ||||
| 				word-wrap: break-word; | ||||
| 			} | ||||
| 			.help { | ||||
| 				margin-left: @input-padding+15px; | ||||
| 			} | ||||
| 			.dropdown { | ||||
| 				.dropdown.icon { | ||||
| 					margin-top: -7px!important; | ||||
| @ -50,13 +63,6 @@ | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			.optional .title { | ||||
| 				margin-left: @input-padding; | ||||
| 			} | ||||
| 			input, | ||||
| 			textarea { | ||||
| 				width: 50%!important; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| @ -66,7 +72,7 @@ | ||||
| 				width: 50%!important; | ||||
| 			} | ||||
| 			#auto-init { | ||||
| 				margin-left: @input-padding+15px; | ||||
| 				margin-left: @create-page-form-input-padding+15px; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -14,4 +14,8 @@ | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	&.new.org { | ||||
| 		#create-page-form; | ||||
| 	} | ||||
| } | ||||
| @ -59,25 +59,18 @@ func CreatePost(ctx *middleware.Context, form auth.CreateOrgForm) { | ||||
| 
 | ||||
| 	org := &models.User{ | ||||
| 		Name:     form.OrgName, | ||||
| 		Email:    form.Email, | ||||
| 		IsActive: true, | ||||
| 		Type:     models.ORGANIZATION, | ||||
| 	} | ||||
| 
 | ||||
| 	var err error | ||||
| 	if err = models.CreateOrganization(org, ctx.User); err != nil { | ||||
| 	if err := models.CreateOrganization(org, ctx.User); err != nil { | ||||
| 		ctx.Data["Err_OrgName"] = true | ||||
| 		switch { | ||||
| 		case models.IsErrUserAlreadyExist(err): | ||||
| 			ctx.Data["Err_OrgName"] = true | ||||
| 			ctx.RenderWithErr(ctx.Tr("form.org_name_been_taken"), CREATE, &form) | ||||
| 		case models.IsErrEmailAlreadyUsed(err): | ||||
| 			ctx.Data["Err_Email"] = true | ||||
| 			ctx.RenderWithErr(ctx.Tr("form.email_been_used"), CREATE, &form) | ||||
| 		case models.IsErrNameReserved(err): | ||||
| 			ctx.Data["Err_OrgName"] = true | ||||
| 			ctx.RenderWithErr(ctx.Tr("org.form.name_reserved", err.(models.ErrNameReserved).Name), CREATE, &form) | ||||
| 		case models.IsErrNamePatternNotAllowed(err): | ||||
| 			ctx.Data["Err_OrgName"] = true | ||||
| 			ctx.RenderWithErr(ctx.Tr("org.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), CREATE, &form) | ||||
| 		default: | ||||
| 			ctx.Handle(500, "CreateOrganization", err) | ||||
|  | ||||
| @ -61,19 +61,11 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateOrgSettingForm) { | ||||
| 	} | ||||
| 
 | ||||
| 	org.FullName = form.OrgFullName | ||||
| 	org.Email = form.Email | ||||
| 	org.Description = form.Description | ||||
| 	org.Website = form.Website | ||||
| 	org.Location = form.Location | ||||
| 	org.Avatar = base.EncodeMd5(form.Avatar) | ||||
| 	org.AvatarEmail = form.Avatar | ||||
| 	if err := models.UpdateUser(org); err != nil { | ||||
| 		if models.IsErrEmailAlreadyUsed(err) { | ||||
| 			ctx.Data["Err_Email"] = true | ||||
| 			ctx.RenderWithErr(ctx.Tr("form.email_been_used"), SETTINGS_OPTIONS, &form) | ||||
| 		} else { | ||||
| 			ctx.Handle(500, "UpdateUser", err) | ||||
| 		} | ||||
| 		ctx.Handle(500, "UpdateUser", err) | ||||
| 		return | ||||
| 	} | ||||
| 	log.Trace("Organization setting updated: %s", org.Name) | ||||
|  | ||||
| @ -1,31 +1,30 @@ | ||||
| {{template "ng/base/head" .}} | ||||
| {{template "ng/base/header" .}} | ||||
| <div id="sign-wrapper"> | ||||
|     <form class="form-align form panel sign-panel sign-form container panel-radius" id="sign-up-form" action="{{AppSubUrl}}/org/create" method="post"> | ||||
| {{template "base/head" .}} | ||||
| <div class="organization new org"> | ||||
|   <div class="ui middle very relaxed page grid"> | ||||
|     <div class="column"> | ||||
|       <form class="ui form" action="{{.Link}}" method="post"> | ||||
|         {{.CsrfTokenHtml}} | ||||
|         <div class="panel-header"> | ||||
|             <h2>{{.i18n.Tr "new_org"}}</h2> | ||||
|         <h3 class="ui top attached header"> | ||||
|           {{.i18n.Tr "new_org"}} | ||||
|         </h3> | ||||
|         <div class="ui attached segment"> | ||||
|           {{template "base/alert" .}} | ||||
|           <div class="inline required field {{if .Err_OrgName}}error{{end}}"> | ||||
|             <label for="org_name">{{.i18n.Tr "org.org_name_holder"}}</label> | ||||
|             <input id="org_name" name="org_name" value="{{.org_name}}" autofocus required> | ||||
|             <span class="help">{{.i18n.Tr "org.org_name_helper"}}</span> | ||||
|           </div> | ||||
| 
 | ||||
|           <div class="inline field"> | ||||
|             <label></label> | ||||
|             <button class="ui green button"> | ||||
|               {{.i18n.Tr "org.create_org"}} | ||||
|             </button> | ||||
|             <a class="ui button" href="{{AppSubUrl}}/">{{.i18n.Tr "cancel"}}</a> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="panel-content"> | ||||
|             {{template "ng/base/alert" .}} | ||||
|             <div class="field"> | ||||
|                 <label class="req" for="org_name">{{.i18n.Tr "org.org_name_holder"}}</label> | ||||
|                 <input class="ipt ipt-large ipt-radius {{if .Err_OrgName}}ipt-error{{end}}" id="org_name" name="org_name" type="text" value="{{.org_name}}" required/> | ||||
|                 <label></label> | ||||
|                 <span class="help">{{.i18n.Tr "org.org_name_helper"}}</span> | ||||
|             </div> | ||||
|             <div class="field"> | ||||
|                 <label class="req" for="email">{{.i18n.Tr "email"}}</label> | ||||
|                 <input class="ipt ipt-large ipt-radius {{if .Err_Email}}ipt-error{{end}}" id="email" name="email" type="email" value="{{.email}}" required/> | ||||
|                 <label></label> | ||||
|                 <span class="help">{{.i18n.Tr "org.org_email_helper"}}</span> | ||||
|             </div> | ||||
|             <div class="field"> | ||||
|                 <span class="form-label"></span> | ||||
|                 <button class="btn btn-large btn-blue btn-radius">{{.i18n.Tr "org.create_org"}}</button> | ||||
|                 <a class="btn btn-small btn-gray btn-radius" id="repo-create-cancel" href="{{AppSubUrl}}/"><strong>{{.i18n.Tr "cancel"}}</strong></a> | ||||
|             </div> | ||||
|         </div> | ||||
|     </form> | ||||
|       </form> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| {{template "ng/base/footer" .}} | ||||
| {{template "base/footer" .}} | ||||
| @ -30,10 +30,6 @@ | ||||
|                 <label for="full-name">{{.i18n.Tr "org.settings.full_name"}}</label> | ||||
|                 <input class="ipt ipt-large ipt-radius {{if .Err_FullName}}ipt-error{{end}}" id="full-name" name="fullname" value="{{.Org.FullName}}" /> | ||||
|               </div> | ||||
|               <div class="field"> | ||||
|                 <label class="req" for="email">{{.i18n.Tr "email"}}</label> | ||||
|                 <input class="ipt ipt-large ipt-radius {{if .Err_Email}}ipt-error{{end}}" id="email" name="email" type="email" value="{{.Org.Email}}" required /> | ||||
|               </div> | ||||
|               <div class="field clear"> | ||||
|                 <label class="left" for="desc">{{.i18n.Tr "org.org_desc"}}</label> | ||||
|                 <textarea class="ipt ipt-large ipt-radius {{if .Err_Description}}ipt-error{{end}}" id="desc" name="desc">{{.Org.Description}}</textarea> | ||||
| @ -46,10 +42,6 @@ | ||||
|                 <label for="location">{{.i18n.Tr "org.settings.location"}}</label> | ||||
|                 <input class="ipt ipt-large ipt-radius {{if .Err_Location}}ipt-error{{end}}" id="location" name="location" type="text" value="{{.Org.Location}}" /> | ||||
|               </div> | ||||
|               <div class="field {{if DisableGravatar}}hide{{end}}"> | ||||
|                 <label class="req" for="gravatar-email">Gravatar {{.i18n.Tr "email"}}</label> | ||||
|                 <input class="ipt ipt-large ipt-radius {{if .Err_Avatar}}ipt-error{{end}}" id="gravatar-email" name="avatar" type="text" value="{{.Org.AvatarEmail}}" /> | ||||
|               </div> | ||||
|               <div class="field"> | ||||
|                 <span class="form-label"></span> | ||||
|                 <button class="btn btn-green btn-large btn-radius" id="change-orgname-btn" href="#change-orgname-modal">{{.i18n.Tr "org.settings.update_settings"}}</button> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Unknwon
						Unknwon