Add theme selector to the user profile form
parent
a1488d60c8
commit
6d202e923e
|
@ -7,6 +7,7 @@
|
|||
- Ability to create single-line or multi-line custom fields. (thanks to [@artlepool](https://github.com/artlepool))
|
||||
- Add custom videoconference system.
|
||||
- Make burndown chart collapsible at the backlog panel.
|
||||
- Ability to choose a theme (thanks to [@astagi](https://github.com/astagi))
|
||||
|
||||
### Misc
|
||||
- Improve performance: Show cropped images in timelines.
|
||||
|
|
|
@ -4,6 +4,8 @@ window.taigaConfig = {
|
|||
"eventsUrl": null,
|
||||
"debug": true,
|
||||
"defaultLanguage": "en",
|
||||
"themes": ["taiga"],
|
||||
"defaultTheme": "taiga",
|
||||
"publicRegisterEnabled": true,
|
||||
"feedbackEnabled": true,
|
||||
"privacyPolicyUrl": null,
|
||||
|
|
|
@ -37,9 +37,11 @@ class AuthService extends taiga.Service
|
|||
"$tgUrls",
|
||||
"$tgConfig",
|
||||
"$translate",
|
||||
"tgCurrentUserService"]
|
||||
"tgCurrentUserService",
|
||||
"tgThemeService"]
|
||||
|
||||
constructor: (@rootscope, @storage, @model, @rs, @http, @urls, @config, @translate, @currentUserService) ->
|
||||
constructor: (@rootscope, @storage, @model, @rs, @http, @urls, @config, @translate, @currentUserService,
|
||||
@themeService) ->
|
||||
super()
|
||||
userModel = @.getUser()
|
||||
@.setUserdata(userModel)
|
||||
|
@ -51,9 +53,12 @@ class AuthService extends taiga.Service
|
|||
else
|
||||
@.userData = null
|
||||
|
||||
_setTheme: ->
|
||||
theme = @rootscope.user?.theme || @config.get("defaultTheme") || "taiga"
|
||||
@themeService.use(theme)
|
||||
|
||||
_setLocales: ->
|
||||
lang = @rootscope.user.lang || @config.get("defaultLanguage") || "en"
|
||||
lang = @rootscope.user?.lang || @config.get("defaultLanguage") || "en"
|
||||
@translate.preferredLanguage(lang) # Needed for calls to the api in the correct language
|
||||
@translate.use(lang) # Needed for change the interface in runtime
|
||||
|
||||
|
@ -66,6 +71,7 @@ class AuthService extends taiga.Service
|
|||
user = @model.make_model("users", userData)
|
||||
@rootscope.user = user
|
||||
@._setLocales()
|
||||
@._setTheme()
|
||||
return user
|
||||
|
||||
return null
|
||||
|
@ -78,6 +84,7 @@ class AuthService extends taiga.Service
|
|||
@.setUserdata(user)
|
||||
|
||||
@._setLocales()
|
||||
@._setTheme()
|
||||
|
||||
clear: ->
|
||||
@rootscope.auth = null
|
||||
|
@ -117,9 +124,12 @@ class AuthService extends taiga.Service
|
|||
logout: ->
|
||||
@.removeToken()
|
||||
@.clear()
|
||||
|
||||
@currentUserService.removeUser()
|
||||
|
||||
@._setTheme()
|
||||
@._setLocales()
|
||||
|
||||
|
||||
register: (data, type, existing) ->
|
||||
url = @urls.resolve("auth-register")
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ class UserSettingsController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
@location.replace()
|
||||
|
||||
@scope.lang = @getLan()
|
||||
@scope.theme = @getTheme()
|
||||
|
||||
maxFileSize = @config.get("maxUploadFileSize", null)
|
||||
if maxFileSize
|
||||
|
@ -68,6 +69,8 @@ class UserSettingsController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
loadInitialData: ->
|
||||
@scope.availableThemes = @config.get("themes", [])
|
||||
|
||||
return @rs.locales.list().then (locales) =>
|
||||
@scope.locales = locales
|
||||
return locales
|
||||
|
@ -79,6 +82,11 @@ class UserSettingsController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
return @scope.user.lang ||
|
||||
@translate.preferredLanguage()
|
||||
|
||||
getTheme: ->
|
||||
return @scope.user.theme ||
|
||||
@config.get("defaultTheme") ||
|
||||
"taiga"
|
||||
|
||||
module.controller("UserSettingsController", UserSettingsController)
|
||||
|
||||
|
||||
|
@ -96,6 +104,7 @@ UserProfileDirective = ($confirm, $auth, $repo, $translate) ->
|
|||
|
||||
changeEmail = $scope.user.isAttributeModified("email")
|
||||
$scope.user.lang = $scope.lang
|
||||
$scope.user.theme = $scope.theme
|
||||
|
||||
onSuccess = (data) =>
|
||||
$auth.setUser(data)
|
||||
|
|
|
@ -1193,7 +1193,9 @@
|
|||
"BIO": "Bio (max. 210 chars)",
|
||||
"PLACEHOLDER_BIO": "Tell us something about you",
|
||||
"LANGUAGE": "Language",
|
||||
"LANGUAGE_DEFAULT": "-- use default language --"
|
||||
"LANGUAGE_DEFAULT": "-- use default language --",
|
||||
"THEME": "Theme",
|
||||
"THEME_DEFAULT": "-- use default theme --"
|
||||
}
|
||||
},
|
||||
"WIZARD": {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
taiga = @.taiga
|
||||
|
||||
|
||||
class ThemeService extends taiga.Service = ->
|
||||
use: (themeName) ->
|
||||
stylesheetEl = $("link[rel='stylesheet']")
|
||||
|
||||
if stylesheetEl.length == 0
|
||||
stylesheetEl = $("<link rel='stylesheet' href='' type='text/css'>")
|
||||
$("head").append(stylesheetEl)
|
||||
|
||||
stylesheetEl.attr("href", "/styles/theme-#{themeName}.css")
|
||||
|
||||
|
||||
angular.module("taigaCommon").service("tgThemeService", ThemeService)
|
|
@ -0,0 +1,17 @@
|
|||
describe "ThemeService", ->
|
||||
themeService = null
|
||||
data = {
|
||||
theme: "testTheme"
|
||||
}
|
||||
|
||||
_inject = () ->
|
||||
inject (_tgThemeService_) ->
|
||||
themeService = _tgThemeService_
|
||||
|
||||
beforeEach ->
|
||||
module "taigaCommon"
|
||||
_inject()
|
||||
|
||||
it "use a test theme", () ->
|
||||
themeService.use(data.theme)
|
||||
expect($("link[rel='stylesheet']")).to.have.attr("href", "/styles/theme-#{data.theme}.css")
|
|
@ -30,7 +30,7 @@ div.wrapper(tg-user-profile, ng-controller="UserSettingsController as ctrl",
|
|||
|
||||
div.data
|
||||
fieldset
|
||||
label(for="email", translate="USER_PROFILE.FIELD.USERNAME")
|
||||
label(for="username", translate="USER_PROFILE.FIELD.USERNAME")
|
||||
input(type="text", name="username", id="username",
|
||||
placeholder="{{'USER_PROFILE.FIELD.USERNAME' | translate}}",
|
||||
ng-model="user.username", data-required="true", data-maxlength="255",
|
||||
|
@ -51,16 +51,23 @@ div.wrapper(tg-user-profile, ng-controller="UserSettingsController as ctrl",
|
|||
data-maxlength="256")
|
||||
|
||||
fieldset
|
||||
label(for="full-name", translate="USER_PROFILE.FIELD.LANGUAGE")
|
||||
select(ng-model="lang",
|
||||
label(for="lang", translate="USER_PROFILE.FIELD.LANGUAGE")
|
||||
select(name="lang", id="lang", ng-model="lang",
|
||||
ng-options="locale.code as locale.name for locale in locales")
|
||||
option(value="", translate="USER_PROFILE.FIELD.LANGUAGE_DEFAULT")
|
||||
|
||||
fieldset
|
||||
label(for="theme", translate="USER_PROFILE.FIELD.THEME")
|
||||
select(name="theme", id="theme", ng-model="theme",
|
||||
ng-options="availableTheme for availableTheme in availableThemes")
|
||||
option(value="", translate="USER_PROFILE.FIELD.THEME_DEFAULT")
|
||||
|
||||
fieldset
|
||||
label(for="bio", translate="USER_PROFILE.FIELD.BIO")
|
||||
|
||||
textarea(name="bio", id="bio", ng-model="user.bio",
|
||||
ng-attr-placeholder="{{'USER_PROFILE.FIELD.PLACEHOLDER_BIO' | translate}}", ng-maxlength="210", maxlength="210")
|
||||
ng-attr-placeholder="{{'USER_PROFILE.FIELD.PLACEHOLDER_BIO' | translate}}",
|
||||
ng-maxlength="210", maxlength="210")
|
||||
|
||||
fieldset.submit
|
||||
button.button-green.submit-button(type="submit", title="{{'COMMON.SAVE' | translate}}",
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
"debug": true,
|
||||
"debugInfo": false,
|
||||
"defaultLanguage": "en",
|
||||
"themes": ["taiga"],
|
||||
"defaultTheme": "taiga",
|
||||
"publicRegisterEnabled": true,
|
||||
"feedbackEnabled": true,
|
||||
"privacyPolicyUrl": null,
|
||||
|
|
Loading…
Reference in New Issue