mirror of
https://github.com/documize/community.git
synced 2025-07-19 13:19:43 +02:00
[WIP] User can select theme
This commit is contained in:
parent
11e164496b
commit
679049d2b1
11 changed files with 141 additions and 8 deletions
|
@ -282,13 +282,12 @@ type searchStatus struct {
|
|||
// Themes returns list of installed UI themes.
|
||||
func (h *Handler) Themes(w http.ResponseWriter, r *http.Request) {
|
||||
type theme struct {
|
||||
Name string `json:"names"`
|
||||
Name string `json:"name"`
|
||||
Primary string `json:"primary"`
|
||||
}
|
||||
|
||||
th := []theme{}
|
||||
|
||||
th = append(th, theme{Name: "Default", Primary: "#280A42"})
|
||||
th = append(th, theme{Name: "", Primary: "#280A42"})
|
||||
th = append(th, theme{Name: "Blue", Primary: "#176091"})
|
||||
th = append(th, theme{Name: "Deep Orange", Primary: "#BF360C"})
|
||||
th = append(th, theme{Name: "Teal", Primary: "#00695C"})
|
||||
|
|
|
@ -13,10 +13,12 @@ import $ from 'jquery';
|
|||
import { empty, and } from '@ember/object/computed';
|
||||
import { isEmpty } from '@ember/utils';
|
||||
import { set } from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
import Notifier from '../../mixins/notifier';
|
||||
import Component from '@ember/component';
|
||||
|
||||
export default Component.extend(Notifier, {
|
||||
appMeta: service(),
|
||||
maxTags: 3,
|
||||
titleEmpty: empty('model.general.title'),
|
||||
messageEmpty: empty('model.general.message'),
|
||||
|
@ -70,6 +72,11 @@ export default Component.extend(Notifier, {
|
|||
set(this, 'messageError', false);
|
||||
set(this, 'conversionEndpointError', false);
|
||||
});
|
||||
},
|
||||
|
||||
onThemeChange(theme) {
|
||||
this.get('appMeta').setTheme(theme);
|
||||
this.set('model.general.theme', theme);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
46
gui/app/components/ui/theme-picker.js
Normal file
46
gui/app/components/ui/theme-picker.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
import { inject as service } from '@ember/service';
|
||||
import { set } from '@ember/object';
|
||||
import Component from '@ember/component';
|
||||
|
||||
export default Component.extend({
|
||||
appMeta: service(),
|
||||
value: '',
|
||||
onChange: null,
|
||||
|
||||
didReceiveAttrs() {
|
||||
this._super(...arguments);
|
||||
|
||||
let defTheme = this.get('appMeta.theme');
|
||||
this.get('appMeta').getThemes().then((themes) => {
|
||||
_.each(themes, (theme) => {
|
||||
theme.selected = theme.name === defTheme ? true: false;
|
||||
if (theme.name === '') theme.name = 'Default';
|
||||
});
|
||||
|
||||
this.set('themes', themes);
|
||||
});
|
||||
},
|
||||
|
||||
actions: {
|
||||
onSelect(selectedTheme) {
|
||||
let themes = this.get('themes');
|
||||
if (this.get('onChange') !== null) {
|
||||
_.each(themes, (theme) => {
|
||||
set(theme, 'selected', theme.name === selectedTheme ? true: false);
|
||||
});
|
||||
this.get('onChange')(selectedTheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
|
@ -11,12 +11,14 @@
|
|||
|
||||
import $ from 'jquery';
|
||||
import { empty } from '@ember/object/computed';
|
||||
import Component from '@ember/component';
|
||||
import { computed, set } from '@ember/object';
|
||||
import { isPresent, isEqual, isEmpty } from '@ember/utils';
|
||||
import { inject as service } from '@ember/service';
|
||||
import AuthProvider from '../mixins/auth';
|
||||
import Component from '@ember/component';
|
||||
|
||||
export default Component.extend(AuthProvider, {
|
||||
appMeta: service(),
|
||||
hasFirstnameError: empty('model.firstname'),
|
||||
hasLastnameError: empty('model.lastname'),
|
||||
hasEmailError: computed('model.email', function() {
|
||||
|
@ -83,6 +85,11 @@ export default Component.extend(AuthProvider, {
|
|||
set(this, 'password.password', '');
|
||||
set(this, 'password.confirmation', '');
|
||||
});
|
||||
},
|
||||
|
||||
onThemeChange(theme) {
|
||||
this.get('appMeta').setTheme(theme);
|
||||
this.set('model.theme', theme);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -19,6 +19,7 @@ export default Model.extend({
|
|||
conversionEndpoint: attr('string'),
|
||||
allowAnonymousAccess: attr('boolean', { defaultValue: false }),
|
||||
maxTags: attr('number', {defaultValue: 3}),
|
||||
theme: attr('string'),
|
||||
created: attr(),
|
||||
revised: attr()
|
||||
});
|
||||
|
|
|
@ -27,6 +27,7 @@ export default Model.extend({
|
|||
accounts: attr(),
|
||||
groups: attr(),
|
||||
lastVersion: attr('string'),
|
||||
theme: attr('string'),
|
||||
created: attr(),
|
||||
revised: attr(),
|
||||
|
||||
|
|
|
@ -120,10 +120,22 @@ export default Service.extend({
|
|||
},
|
||||
|
||||
setTheme(theme) {
|
||||
theme = theme.trim();
|
||||
if (theme.length === 0) return;
|
||||
$('#theme-link').remove();
|
||||
|
||||
theme = theme.toLowerCase().replace(' ', '-').replace('default', '').trim();
|
||||
if (theme.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let file = this.get('assetMap').resolve(`assets/theme-${theme}.css`);
|
||||
$('head').append(`<link rel="stylesheet" href="${file}">`);
|
||||
$('head').append(`<link id="theme-link" rel="stylesheet" href="${file}">`);
|
||||
},
|
||||
|
||||
getThemes() {
|
||||
return this.get('ajax').request(`public/meta/themes`, {
|
||||
method: 'GET'
|
||||
}).then((response) => {
|
||||
return response;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -32,3 +32,37 @@
|
|||
color: $color-gray;
|
||||
margin: 5rem 0;
|
||||
}
|
||||
|
||||
|
||||
.theme-picker {
|
||||
display : block;
|
||||
margin-bottom: 10px;
|
||||
|
||||
> .theme {
|
||||
height: 100px;
|
||||
width: 250px;
|
||||
text-align: center;
|
||||
color: $color-white;
|
||||
font-weight: 600;
|
||||
font-size: 1.2rem;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
margin: 0 20px 20px 0;
|
||||
padding: 10px 0 0 0;
|
||||
cursor: default;
|
||||
border: 7px solid $color-gray-light;
|
||||
@include border-radius(3px);
|
||||
@include ease-in();
|
||||
|
||||
&:hover {
|
||||
border: 7px solid $color-gray;
|
||||
}
|
||||
|
||||
.tick {
|
||||
text-align: center;
|
||||
color: $color-white;
|
||||
font-weight: 400;
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,14 @@
|
|||
<small class="form-text text-muted">How many tags can be assigned to a document (between 3 and 10 tags)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label">Default Site Theme</label>
|
||||
<div class="col-sm-7">
|
||||
{{ui/theme-picker onChange=(action 'onThemeChange')}}
|
||||
<small class="form-text text-muted">Users can set their own theme under Profile</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn btn-success font-weight-bold text-uppercase mt-4" {{action 'save'}}>Save</div>
|
||||
</form>
|
||||
</div>
|
14
gui/app/templates/components/ui/theme-picker.hbs
Normal file
14
gui/app/templates/components/ui/theme-picker.hbs
Normal file
|
@ -0,0 +1,14 @@
|
|||
<div class="theme-picker">
|
||||
{{#each themes as |theme|}}
|
||||
<div class="theme" style="{{concat 'background-color: ' theme.primary}}" {{action 'onSelect' theme.name}}>
|
||||
{{theme.name}}
|
||||
<div class="tick">
|
||||
{{#if theme.selected}}
|
||||
✓
|
||||
{{else}}
|
||||
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
|
@ -20,6 +20,10 @@
|
|||
<label for="confirmPassword">Confirm Password</label>
|
||||
{{input id="confirmPassword" type="password" value=password.confirmation class=(if hasConfirmPasswordError 'form-control is-invalid' 'form-control')}}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Theme</label>
|
||||
{{ui/theme-picker onChange=(action 'onThemeChange')}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="btn btn-success" {{action 'save'}}>Save</div>
|
||||
<div class="btn btn-success my-5" {{action 'save'}}>Save</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue