Browse Source

Merge pull request 'user_resources' (#100) from user_resources into dev_mirocod

Reviewed-on: http://git.mirocod.ru/MIROCOD/Platform_Mirocod/pulls/100
pull/114/head
parent
commit
bf0ca4662a
  1. 2
      models/migrations/migrations.go
  2. 28
      models/migrations/v211.go
  3. 3
      models/user/user.go
  4. 5
      options/locale/locale_ru-RU.ini
  5. 3
      routers/web/admin/users.go
  6. 60
      routers/web/org/home.go
  7. 2
      routers/web/org/setting.go
  8. 62
      routers/web/user/profile.go
  9. 3
      routers/web/user/setting/profile.go
  10. 3
      services/forms/admin.go
  11. 2
      services/forms/org.go
  12. 3
      services/forms/user_form.go
  13. 12
      templates/admin/user/edit.tmpl
  14. 13
      templates/org/home.tmpl
  15. 8
      templates/org/settings/options.tmpl
  16. 19
      templates/user/profile.tmpl
  17. 12
      templates/user/settings/profile.tmpl

2
models/migrations/migrations.go

@ -373,6 +373,8 @@ var migrations = []Migration{
NewMigration("Increase WebAuthentication CredentialID size to 410 - NO-OPED", increaseCredentialIDTo410),
// v210 -> v211
NewMigration("v208 was completely broken - remigrate", remigrateU2FCredentials),
// v211 -> v212
NewMigration("add competences, resources, interests to user tbl", addTrustedPropsToUser),
}
// GetCurrentDBVersion returns the current db version

28
models/migrations/v211.go

@ -0,0 +1,28 @@
package migrations
import (
"fmt"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
)
func addTrustedPropsToUser(engine *xorm.Engine) error {
var err error
tableName := "user"
switch engine.Dialect().URI().DBType {
case schemas.POSTGRES:
addColsQuery := fmt.Sprintf("ALTER TABLE \"%s\" ADD COLUMN competences TEXT, ADD COLUMN resources TEXT, ADD COLUMN interests TEXT;", tableName)
_, err = engine.Exec(addColsQuery)
case schemas.SQLITE:
addColsQuery := fmt.Sprintf("ALTER TABLE \"%s\" ADD COLUMN competences TEXT;\nALTER TABLE \"%s\" ADD COLUMN resources TEXT;\nALTER TABLE \"%s\" ADD COLUMN interests TEXT;", tableName, tableName, tableName)
_, err = engine.Exec(addColsQuery)
case schemas.MYSQL:
addColsQuery := fmt.Sprintf("ALTER TABLE `%s` ADD COLUMN competences TEXT, ADD COLUMN resources TEXT, ADD COLUMN interests TEXT;", tableName)
_, err = engine.Exec(addColsQuery)
}
if err != nil {
return fmt.Errorf("Ошибка добавление колонок компетенций и тд: %v", err)
} else {
return nil
}
}

3
models/user/user.go

@ -100,6 +100,9 @@ type User struct {
Salt string `xorm:"VARCHAR(32)"`
Language string `xorm:"VARCHAR(5)"`
Description string `xorm:"TEXT"`
Competences string `xorm:"TEXT"`
Resources string `xorm:"TEXT"`
Interests string `xorm:"TEXT"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`

5
options/locale/locale_ru-RU.ini

@ -494,6 +494,9 @@ follow=Подписаться
unfollow=Отписаться
heatmap.loading=Загрузка тепловой карты…
user_bio=О себе
user_competences=Компетенции
user_resources=Ресурсы
user_interests=Интересы
disabled_public_activity=Этот пользователь отключил публичную видимость активности.
form.name_reserved=Имя пользователя '%s' зарезервировано.
@ -2201,6 +2204,8 @@ lower_repositories=Проекты
create_new_team=Создание команды
create_team=Создать команду
org_desc=Описание
org_competences=Компетенции
org_resources=Ресурсы
team_name=Название команды
team_desc=Описание
team_name_helper=Названия команд должны быть короткими и запоминающимися.

3
routers/web/admin/users.go

@ -372,6 +372,9 @@ func EditUserPost(ctx *context.Context) {
u.Email = form.Email
u.Website = form.Website
u.Description = form.Description
u.Competences = form.Competences
u.Resources = form.Resources
u.Interests = form.Interests
u.Location = form.Location
u.LocationCoordinate = form.LocationCoordinate
u.MaxRepoCreation = form.MaxRepoCreation

60
routers/web/org/home.go

@ -5,7 +5,9 @@
package org
import (
"fmt"
"net/http"
"reflect"
"strings"
"code.gitea.io/gitea/models"
@ -46,17 +48,24 @@ func Home(ctx *context.Context) {
ctx.Data["PageIsUserProfile"] = true
ctx.Data["Title"] = org.DisplayName()
if len(org.Description) != 0 {
desc, err := markdown.RenderString(&markup.RenderContext{
URLPrefix: ctx.Repo.RepoLink,
Metas: map[string]string{"mode": "document"},
GitRepo: ctx.Repo.GitRepo,
}, org.Description)
if err != nil {
ctx.ServerError("RenderString", err)
return
}
ctx.Data["RenderedDescription"] = desc
var renderErr error
renderErr = getRenderedTextField(ctx, org, "Description")
if renderErr != nil {
ctx.ServerError("RenderString", renderErr)
return
}
renderErr = getRenderedTextField(ctx, org, "Competences")
if renderErr != nil {
ctx.ServerError("RenderString", renderErr)
return
}
renderErr = getRenderedTextField(ctx, org, "Resources")
if renderErr != nil {
ctx.ServerError("RenderString", renderErr)
return
}
var orderBy db.SearchOrderBy
@ -159,3 +168,32 @@ func Home(ctx *context.Context) {
ctx.HTML(http.StatusOK, tplOrgHome)
}
func getTextField(user *models.Organization, fieldName string) string {
reflectedObj := reflect.ValueOf(user)
dynamicField := reflect.Indirect(reflectedObj).FieldByName(fieldName)
return dynamicField.String()
}
/**
Приходится дублировать код, т.к. не получилось вынести эту функцию и функцию getTextField в services,
т.к. modules/context/context.go зависит от models/user.
*/
func getRenderedTextField(ctx *context.Context, ctxUser *models.Organization, fieldName string) error {
var err error = nil
var content string
fieldVal := getTextField(ctxUser, fieldName)
if len(fieldVal) != 0 {
content, err = markdown.RenderString(&markup.RenderContext{
URLPrefix: ctx.Repo.RepoLink,
Metas: map[string]string{"mode": "document"},
GitRepo: ctx.Repo.GitRepo,
Ctx: ctx,
}, fieldVal)
if err == nil {
renderedFieldName := fmt.Sprintf("Rendered%s", fieldName)
ctx.Data[renderedFieldName] = content
}
}
return err
}

2
routers/web/org/setting.go

@ -98,6 +98,8 @@ func SettingsPost(ctx *context.Context) {
org.FullName = form.FullName
org.Description = form.Description
org.Competences = form.Competences
org.Resources = form.Resources
org.Website = form.Website
org.Location = form.Location
org.LocationCoordinate = form.LocationCoordinate

62
routers/web/user/profile.go

@ -9,6 +9,7 @@ import (
"fmt"
"net/http"
"path"
"reflect"
"strings"
"code.gitea.io/gitea/models"
@ -158,18 +159,30 @@ func Profile(ctx *context.Context) {
ctx.Data["HeatmapData"] = data
}
if len(ctxUser.Description) != 0 {
content, err := markdown.RenderString(&markup.RenderContext{
URLPrefix: ctx.Repo.RepoLink,
Metas: map[string]string{"mode": "document"},
GitRepo: ctx.Repo.GitRepo,
Ctx: ctx,
}, ctxUser.Description)
if err != nil {
ctx.ServerError("RenderString", err)
return
}
ctx.Data["RenderedDescription"] = content
var renderErr error
renderErr = getRenderedTextField(ctx, ctxUser, "Description")
if renderErr != nil {
ctx.ServerError("RenderString", renderErr)
return
}
renderErr = getRenderedTextField(ctx, ctxUser, "Competences")
if renderErr != nil {
ctx.ServerError("RenderString", renderErr)
return
}
renderErr = getRenderedTextField(ctx, ctxUser, "Resources")
if renderErr != nil {
ctx.ServerError("RenderString", renderErr)
return
}
renderErr = getRenderedTextField(ctx, ctxUser, "Interests")
if renderErr != nil {
ctx.ServerError("RenderString", renderErr)
return
}
showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == ctxUser.ID)
@ -377,3 +390,28 @@ func Action(ctx *context.Context) {
// FIXME: We should check this URL and make sure that it's a valid Gitea URL
ctx.RedirectToFirst(ctx.FormString("redirect_to"), u.HomeLink())
}
func getTextField(user *user_model.User, fieldName string) string {
reflectedObj := reflect.ValueOf(user)
dynamicField := reflect.Indirect(reflectedObj).FieldByName(fieldName)
return dynamicField.String()
}
func getRenderedTextField(ctx *context.Context, ctxUser *user_model.User, fieldName string) error {
var err error = nil
var content string
fieldVal := getTextField(ctxUser, fieldName)
if len(fieldVal) != 0 {
content, err = markdown.RenderString(&markup.RenderContext{
URLPrefix: ctx.Repo.RepoLink,
Metas: map[string]string{"mode": "document"},
GitRepo: ctx.Repo.GitRepo,
Ctx: ctx,
}, fieldVal)
if err == nil {
renderedFieldName := fmt.Sprintf("Rendered%s", fieldName)
ctx.Data[renderedFieldName] = content
}
}
return err
}

3
routers/web/user/setting/profile.go

@ -121,6 +121,9 @@ func ProfilePost(ctx *context.Context) {
ctx.User.Location = form.Location
ctx.User.LocationCoordinate = form.LocationCoordinate
ctx.User.Description = form.Description
ctx.User.Competences = form.Competences
ctx.User.Resources = form.Resources
ctx.User.Interests = form.Interests
ctx.User.KeepActivityPrivate = form.KeepActivityPrivate
ctx.User.Visibility = form.Visibility
if err := user_model.UpdateUserSetting(ctx.User); err != nil {

3
services/forms/admin.go

@ -42,6 +42,9 @@ type AdminEditUserForm struct {
Password string `binding:"MaxSize(255)"`
Website string `binding:"ValidUrl;MaxSize(255)"`
Description string `binding:"MaxSize(1024)"`
Competences string `binding:"MaxSize(1024)"`
Resources string `binding:"MaxSize(1024)"`
Interests string `binding:"MaxSize(1024)"`
Location string `binding:"MaxSize(50)"`
LocationCoordinate string `binding:"MaxSize(255)"`
MaxRepoCreation int

2
services/forms/org.go

@ -40,6 +40,8 @@ type UpdateOrgSettingForm struct {
Name string `binding:"Required;AlphaDashDot;MaxSize(40)" locale:"org.org_name_holder"`
FullName string `binding:"MaxSize(100)"`
Description string `binding:"MaxSize(1024)"`
Competences string `binding:"MaxSize(1024)"`
Resources string `binding:"MaxSize(1024)"`
Website string `binding:"ValidUrl;MaxSize(255)"`
Location string `binding:"MaxSize(50)"`
LocationCoordinate string `binding:"MaxSize(255)"`

3
services/forms/user_form.go

@ -247,6 +247,9 @@ type UpdateProfileForm struct {
Location string `binding:"MaxSize(50)"`
LocationCoordinate string `binding:"MaxSize(255)"`
Description string `binding:"MaxSize(1024)"`
Competences string `binding:"MaxSize(1024)"`
Resources string `binding:"MaxSize(1024)"`
Interests string `binding:"MaxSize(1024)"`
Visibility structs.VisibleType
KeepActivityPrivate bool
}

12
templates/admin/user/edit.tmpl

@ -77,6 +77,18 @@
<label for="description">{{$.i18n.Tr "user.user_bio"}}</label>
<textarea id="description" name="description" rows="4" placeholder="{{.i18n.Tr "settings.biography_placeholder"}}">{{.User.Description}}</textarea>
</div>
<div class="field {{if .Err_Competences}}error{{end}}">
<label for="competences">{{$.i18n.Tr "user.user_competences"}}</label>
<textarea id="competences" name="competences" rows="4">{{.User.Competences}}</textarea>
</div>
<div class="field {{if .Err_Resources}}error{{end}}">
<label for="resources">{{$.i18n.Tr "user.user_resources"}}</label>
<textarea id="resources" name="resources" rows="4">{{.User.Resources}}</textarea>
</div>
<div class="field {{if .Err_Interests}}error{{end}}">
<label for="interests">{{$.i18n.Tr "user.user_interests"}}</label>
<textarea id="interests" name="interests" rows="4">{{.User.Interests}}</textarea>
</div>
<div class="field {{if .Err_Website}}error{{end}}">
<label for="website">{{.i18n.Tr "settings.website"}}</label>
<input id="website" name="website" type="url" value="{{.User.Website}}" placeholder="e.g. http://mydomain.com or https://mydomain.com">

13
templates/org/home.tmpl

@ -10,7 +10,18 @@
{{if .Org.Visibility.IsPrivate}}<div class="ui large basic horizontal label">{{.i18n.Tr "org.settings.visibility.private_shortname"}}</div>{{end}}
</span>
</div>
{{if $.RenderedDescription}}<p class="render-content markup">{{$.RenderedDescription|Str2html}}</p>{{end}}
{{if $.RenderedDescription}}
<h3>{{.i18n.Tr "org.org_desc"}}</h3>
<p class="render-content markup">{{$.RenderedDescription|Str2html}}</p>
{{end}}
{{if $.RenderedCompetences}}
<h3>{{.i18n.Tr "org.org_competences"}}</h3>
<p class="render-content markup">{{$.RenderedCompetences|Str2html}}</p>
{{end}}
{{if $.RenderedResources}}
<h3>{{.i18n.Tr "org.org_resources"}}</h3>
<p class="render-content markup">{{$.RenderedResources|Str2html}}</p>
{{end}}
<div class="text grey meta">
{{if .Org.Location}}<div class="item">{{svg "octicon-location"}} <span>{{.Org.Location}}</span> <span>({{.Org.LocationCoordinate}})</span></div>{{end}}
{{if .Org.Website}}<div class="item">{{svg "octicon-link"}} <a target="_blank" rel="noopener noreferrer" href="{{.Org.Website}}">{{.Org.Website}}</a></div>{{end}}

8
templates/org/settings/options.tmpl

@ -27,6 +27,14 @@
<label for="description">{{$.i18n.Tr "org.org_desc"}}</label>
<textarea id="description" name="description" rows="2">{{.Org.Description}}</textarea>
</div>
<div class="field {{if .Err_Competences}}error{{end}}">
<label for="competences">{{$.i18n.Tr "org.org_competences"}}</label>
<textarea id="competences" name="competences" rows="2">{{.Org.Competences}}</textarea>
</div>
<div class="field {{if .Err_Resources}}error{{end}}">
<label for="resources">{{$.i18n.Tr "org.org_resources"}}</label>
<textarea id="resources" name="resources" rows="2">{{.Org.Resources}}</textarea>
</div>
<div class="field {{if .Err_Website}}error{{end}}">
<label for="website">{{.i18n.Tr "org.settings.website"}}</label>
<input id="website" name="website" type="url" value="{{.Org.Website}}">

19
templates/user/profile.tmpl

@ -36,9 +36,28 @@
{{end}}
{{if $.RenderedDescription}}
<li>
<h3>{{.i18n.Tr "user.user_bio"}}</h3>
<div class="render-content markup">{{$.RenderedDescription|Str2html}}</div>
</li>
{{end}}
{{if $.RenderedCompetences}}
<li>
<h3>{{.i18n.Tr "user.user_competences"}}</h3>
<div class="render-content markup">{{$.RenderedCompetences|Str2html}}</div>
</li>
{{end}}
{{if $.RenderedResources}}
<li>
<h3>{{.i18n.Tr "user.user_resources"}}</h3>
<div class="render-content markup">{{$.RenderedResources|Str2html}}</div>
</li>
{{end}}
{{if $.RenderedInterests}}
<li>
<h3>{{.i18n.Tr "user.user_interests"}}</h3>
<div class="render-content markup">{{$.RenderedInterests|Str2html}}</div>
</li>
{{end}}
{{range .OpenIDs}}
{{if .Show}}
<li>

12
templates/user/settings/profile.tmpl

@ -38,6 +38,18 @@
<label for="description">{{$.i18n.Tr "user.user_bio"}}</label>
<textarea id="description" name="description" rows="2" placeholder="{{.i18n.Tr "settings.biography_placeholder"}}">{{.SignedUser.Description}}</textarea>
</div>
<div class="field {{if .Err_Competences}}error{{end}}">
<label for="competences">{{$.i18n.Tr "user.user_competences"}}</label>
<textarea id="competences" name="competences" rows="2">{{.SignedUser.Competences}}</textarea>
</div>
<div class="field {{if .Err_Resources}}error{{end}}">
<label for="resources">{{$.i18n.Tr "user.user_resources"}}</label>
<textarea id="resources" name="resources" rows="2">{{.SignedUser.Resources}}</textarea>
</div>
<div class="field {{if .Err_Interests}}error{{end}}">
<label for="interests">{{$.i18n.Tr "user.user_interests"}}</label>
<textarea id="interests" name="interests" rows="2">{{.SignedUser.Interests}}</textarea>
</div>
<div class="field {{if .Err_Website}}error{{end}}">
<label for="website">{{.i18n.Tr "settings.website"}}</label>
<input id="website" name="website" type="url" value="{{.SignedUser.Website}}">

Loading…
Cancel
Save