Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1397,6 +1397,7 @@ public class ApiConstants {
public static final String CSS = "css";

public static final String JSON_CONFIGURATION = "jsonconfiguration";
public static final String CUSTOM_LABELS_PATH = "customlabelspath";

public static final String COMMON_NAMES = "commonnames";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ public class CreateGuiThemeCmd extends BaseCmd {
"retrieved and imported into the GUI when matching the theme access configurations.")
private String jsonConfiguration;

@Parameter(name = ApiConstants.CUSTOM_LABELS_PATH, type = CommandType.STRING, length = 65535, description = "The JSON with the custom labels to be " +
"retrieved and imported into the GUI when matching the theme access configurations.")
private String customLabelsPath;

@Parameter(name = ApiConstants.COMMON_NAMES, type = CommandType.STRING, length = 65535, description = "A set of Common Names (CN) (fixed or " +
"wildcard) separated by comma that can retrieve the theme; e.g.: *acme.com,acme2.com")
private String commonNames;
Expand Down Expand Up @@ -89,6 +93,10 @@ public String getJsonConfiguration() {
return jsonConfiguration;
}

public String getCustomLabelsPath() {
return customLabelsPath;
}

public String getCommonNames() {
return commonNames;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ public class UpdateGuiThemeCmd extends BaseCmd {
"retrieved and imported into the GUI when matching the theme access configurations.")
private String jsonConfiguration;

@Parameter(name = ApiConstants.CUSTOM_LABELS_PATH, type = CommandType.STRING, length = 65535, description = "The JSON with the custom labels to be " +
"retrieved and imported into the GUI when matching the theme access configurations.")
private String customLabelsPath;

@Parameter(name = ApiConstants.COMMON_NAMES, type = CommandType.STRING, length = 65535, description = "A set of Common Names (CN) (fixed or " +
"wildcard) separated by comma that can retrieve the theme; e.g.: *acme.com,acme2.com")
private String commonNames;
Expand Down Expand Up @@ -96,6 +100,10 @@ public String getJsonConfiguration() {
return jsonConfiguration;
}

public String getCustomLabelsPath() {
return customLabelsPath;
}

public String getCommonNames() {
return commonNames;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public class GuiThemeResponse extends BaseResponse {
@Param(description = "The JSON with the configurations to be retrieved and imported into the GUI when matching the theme access configurations.")
private String jsonConfiguration;

@SerializedName(ApiConstants.CUSTOM_LABELS_PATH)
@Param(description = "The JSON with the custom labels to be retrieved and imported into the GUI when matching the theme access configurations.")
private String customLabelsPath;

@SerializedName(ApiConstants.COMMON_NAMES)
@Param(description = "A set of Common Names (CN) (fixed or wildcard) separated by comma that can retrieve the theme; e.g.: *acme.com,acme2.com")
private String commonNames;
Expand Down Expand Up @@ -121,6 +125,14 @@ public void setJsonConfiguration(String jsonConfiguration) {
this.jsonConfiguration = jsonConfiguration;
}

public String getCustomLabelsPath() {
return customLabelsPath;
}

public void setCustomLabelsPath(String customLabelsPath) {
this.customLabelsPath = customLabelsPath;
}

public String getCommonNames() {
return commonNames;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public interface GuiTheme extends InternalIdentity, Identity {

boolean getIsPublic();

String getCustomLabelsPath();

void setId(Long id);

void setUuid(String uuid);
Expand All @@ -58,4 +60,6 @@ public interface GuiTheme extends InternalIdentity, Identity {
boolean isRecursiveDomains();

void setRecursiveDomains(boolean recursiveDomains);

void setCustomLabelsPath(String customLabelsPath);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,6 @@ public interface GuiThemeJoin extends InternalIdentity, Identity {
Date getCreated();

Date getRemoved();

String getCustomLabelsPath();
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ public class GuiThemeJoinVO implements GuiThemeJoin {
@Column(name = "json_configuration", nullable = false, length = 65535)
private String jsonConfiguration;

@Column(name = "custom_labels_path", nullable = false, length = 65535)
private String customLabelsPath;

@Column(name = "common_names", length = 65535)
private String commonNames;

Expand All @@ -74,6 +77,24 @@ public class GuiThemeJoinVO implements GuiThemeJoin {
public GuiThemeJoinVO() {
}

public GuiThemeJoinVO(Long id, String uuid, String name, String description, String css, String jsonConfiguration, String customLabelsPath, String commonNames, String domains,
String accounts, boolean recursiveDomains, boolean isPublic, Date created, Date removed) {
this.id = id;
this.uuid = uuid;
this.name = name;
this.description = description;
this.css = css;
this.jsonConfiguration = jsonConfiguration;
this.customLabelsPath = customLabelsPath;
this.commonNames = commonNames;
this.domains = domains;
this.accounts = accounts;
this.recursiveDomains = recursiveDomains;
this.isPublic = isPublic;
this.created = created;
this.removed = removed;
}

@Override
public long getId() {
return id;
Expand Down Expand Up @@ -138,4 +159,9 @@ public Date getCreated() {
public Date getRemoved() {
return removed;
}

@Override
public String getCustomLabelsPath() {
return customLabelsPath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public class GuiThemeVO implements GuiTheme {
@Column(name = "json_configuration", length = 65535)
private String jsonConfiguration;

@Column(name = "custom_labels_path", nullable = false, length = 65535)
private String customLabelsPath;

@Column(name = "is_public")
private boolean isPublic;

Expand All @@ -71,11 +74,12 @@ public GuiThemeVO() {

}

public GuiThemeVO(String name, String description, String css, String jsonConfiguration, boolean recursiveDomains, boolean isPublic, Date created, Date removed) {
public GuiThemeVO(String name, String description, String css, String jsonConfiguration, String customLabelsPath, boolean recursiveDomains, boolean isPublic, Date created, Date removed) {
this.name = name;
this.description = description;
this.css = css;
this.jsonConfiguration = jsonConfiguration;
this.customLabelsPath = customLabelsPath;
this.recursiveDomains = recursiveDomains;
this.isPublic = isPublic;
this.created = created;
Expand Down Expand Up @@ -113,6 +117,10 @@ public String getJsonConfiguration() {
}

@Override
public String getCustomLabelsPath() {
return customLabelsPath;
}

public Date getCreated() {
return created;
}
Expand Down Expand Up @@ -158,6 +166,10 @@ public void setJsonConfiguration(String jsonConfiguration) {
}

@Override
public void setCustomLabelsPath(String customLabelsPath) {
this.customLabelsPath = customLabelsPath;
}

public void setCreated(Date created) {
this.created = created;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,6 @@ INSERT INTO cloud.role_permissions (uuid, role_id, rule, permission, sort_order)
SELECT uuid(), role_id, 'quotaResourceStatement', permission, sort_order
FROM cloud.role_permissions rp
WHERE rule = 'quotaStatement' AND NOT EXISTS(SELECT 1 FROM cloud.role_permissions rp_ WHERE rp.role_id = rp_.role_id AND rp_.rule = 'quotaResourceStatement');

-- Add custom labels to GUI themes
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.gui_themes', 'custom_labels_path', 'TEXT DEFAULT NULL');
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ SELECT
`cloud`.`gui_themes`.`description` AS `description`,
`cloud`.`gui_themes`.`css` AS `css`,
`cloud`.`gui_themes`.`json_configuration` AS `json_configuration`,
`cloud`.`gui_themes`.`custom_labels_path` AS `custom_labels_path`,
(SELECT group_concat(gtd.`value` separator ',') FROM `cloud`.`gui_themes_details` gtd WHERE gtd.`type` = 'commonName' AND gtd.gui_theme_id = `cloud`.`gui_themes`.`id`) common_names,
(SELECT group_concat(gtd.`value` separator ',') FROM `cloud`.`gui_themes_details` gtd WHERE gtd.`type` = 'domain' AND gtd.gui_theme_id = `cloud`.`gui_themes`.`id`) domains,
(SELECT group_concat(gtd.`value` separator ',') FROM `cloud`.`gui_themes_details` gtd WHERE gtd.`type` = 'account' AND gtd.gui_theme_id = `cloud`.`gui_themes`.`id`) accounts,
Expand Down
1 change: 1 addition & 0 deletions server/src/main/java/com/cloud/api/ApiResponseHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -5718,6 +5718,7 @@ public GuiThemeResponse createGuiThemeResponse(GuiThemeJoin guiThemeJoin) {
}

guiThemeResponse.setJsonConfiguration(guiThemeJoin.getJsonConfiguration());
guiThemeResponse.setCustomLabelsPath(guiThemeJoin.getCustomLabelsPath());
guiThemeResponse.setCss(guiThemeJoin.getCss());
guiThemeResponse.setResponseName("guithemes");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ public GuiThemeJoin createGuiTheme(CreateGuiThemeCmd cmd) {
String description = cmd.getDescription();
String css = cmd.getCss();
String jsonConfiguration = cmd.getJsonConfiguration();
String customLabelsPath = cmd.getCustomLabelsPath();
String commonNames = cmd.getCommonNames();
String providedDomainIds = cmd.getDomainIds();
String providedAccountIds = cmd.getAccountIds();
Expand All @@ -140,7 +141,7 @@ public GuiThemeJoin createGuiTheme(CreateGuiThemeCmd cmd) {
isPublic = false;
}

GuiThemeVO guiThemeVO = new GuiThemeVO(name, description, css, jsonConfiguration, recursiveDomains, isPublic, new Date(), null);
GuiThemeVO guiThemeVO = new GuiThemeVO(name, description, css, jsonConfiguration, customLabelsPath, recursiveDomains, isPublic, new Date(), null);
guiThemeDao.persist(guiThemeVO);
persistGuiThemeDetails(guiThemeVO.getId(), commonNames, providedDomainIds, providedAccountIds);
return guiThemeJoinDao.findById(guiThemeVO.getId());
Expand Down Expand Up @@ -264,6 +265,7 @@ public GuiThemeJoin updateGuiTheme(UpdateGuiThemeCmd cmd) {
String description = cmd.getDescription();
String css = cmd.getCss();
String jsonConfiguration = cmd.getJsonConfiguration();
String customLabelsPath = cmd.getCustomLabelsPath();
String commonNames = cmd.getCommonNames() == null ? guiThemeJoinVO.getCommonNames() : cmd.getCommonNames();
String providedDomainIds = cmd.getDomainIds() == null ? guiThemeJoinVO.getDomains() : cmd.getDomainIds();
String providedAccountIds = cmd.getAccountIds() == null ? guiThemeJoinVO.getAccounts() : cmd.getAccountIds();
Expand All @@ -279,11 +281,11 @@ public GuiThemeJoin updateGuiTheme(UpdateGuiThemeCmd cmd) {
isPublic = false;
}

return persistGuiTheme(guiThemeId, name, description, css, jsonConfiguration, commonNames, providedDomainIds, providedAccountIds, isPublic, recursiveDomains);
return persistGuiTheme(guiThemeId, name, description, css, jsonConfiguration, customLabelsPath, commonNames, providedDomainIds, providedAccountIds, isPublic, recursiveDomains);
}

protected GuiThemeJoinVO persistGuiTheme(Long guiThemeId, String name, String description, String css, String jsonConfiguration, String commonNames, String providedDomainIds,
String providedAccountIds, Boolean isPublic, Boolean recursiveDomains){
protected GuiThemeJoinVO persistGuiTheme(Long guiThemeId, String name, String description, String css, String jsonConfiguration, String customLabelsPath, String commonNames, String providedDomainIds,
String providedAccountIds, Boolean isPublic, Boolean recursiveDomains){
return Transaction.execute((TransactionCallback<GuiThemeJoinVO>) status -> {
GuiThemeVO guiThemeVO = guiThemeDao.findById(guiThemeId);

Expand All @@ -303,6 +305,10 @@ protected GuiThemeJoinVO persistGuiTheme(Long guiThemeId, String name, String de
guiThemeVO.setJsonConfiguration(jsonConfiguration);
}

if (customLabelsPath != null) {
guiThemeVO.setCustomLabelsPath(customLabelsPath);
}

if (isPublic != null) {
guiThemeVO.setIsPublic(isPublic);
}
Expand Down
15 changes: 15 additions & 0 deletions ui/src/locales/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { vueProps } from '@/vue-app'

const loadedLanguage = []
const messages = {}
let systemLang

export const i18n = createI18n({
locale: 'en',
Expand All @@ -39,11 +40,23 @@ export function loadLanguageAsync (lang) {
return Promise.resolve(setLanguage(lang))
}

systemLang = lang
return fetch(`locales/${lang}.json?ts=${Date.now()}`)
.then(response => response.json())
.then(json => Promise.resolve(setLanguage(lang, json)))
}

export function updateMessages (customPath) {
fetch(`${customPath}/${systemLang}.json`)
.then(response => response.json())
.then((data) => {
const keys = Object.keys(data)
keys.forEach(x => {
messages[systemLang][x] = data[x]
})
})
}

function setLanguage (lang, message) {
if (i18n) {
i18n.global.locale = lang
Expand All @@ -60,4 +73,6 @@ function setLanguage (lang, message) {
if (message && Object.keys(message).length > 0) {
messages[lang] = message
}

systemLang = lang
}
14 changes: 7 additions & 7 deletions ui/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,14 @@ fetch('config.json?ts=' + Date.now())
})
}

await applyCustomGuiTheme(accountid, domainid)

loadLanguageAsync().then(() => {
vueApp.use(store)
.use(router)
.use(i18n)
.use(bootstrap)
.mount('#app')
applyCustomGuiTheme(accountid, domainid).finally(() => {
vueApp.use(store)
.use(router)
.use(i18n)
.use(bootstrap)
.mount('#app')
})
})
}).catch(error => {
renderError(error)
Expand Down
6 changes: 5 additions & 1 deletion ui/src/utils/guiTheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import { vueProps } from '@/vue-app'
import { getAPI } from '@/api'
import { loadLanguageAsync } from '../locales'
import { loadLanguageAsync, updateMessages } from '../locales'

export async function applyCustomGuiTheme (accountid, domainid) {
await fetch('config.json').then(response => response.json()).then(config => {
Expand Down Expand Up @@ -63,6 +63,10 @@ async function applyDynamicCustomization (response) {
jsonConfig = JSON.parse(response?.jsonconfiguration)
}

if (response?.customlabelspath) {
updateMessages(response.customlabelspath)
}

// Sets custom GUI fields only if is not nullish.
vueProps.$config.appTitle = jsonConfig?.appTitle ?? vueProps.$config.appTitle
vueProps.$config.footer = jsonConfig?.footer ?? vueProps.$config.footer
Expand Down
Loading