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