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
3 changes: 3 additions & 0 deletions api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,9 @@ 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 LOGIN_BASE_DOMAIN = "loginbasedomain";

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 @@ -93,6 +97,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 @@ -100,6 +104,10 @@ public String getJsonConfiguration() {
return jsonConfiguration;
}

public String getCustomLabelsPath() {
return customLabelsPath;
}

public String getLoginBaseDomain() {
return loginBaseDomain;
}
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 @@ -126,6 +130,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 @@ -45,5 +45,7 @@ public interface GuiThemeJoin extends InternalIdentity, Identity {

Date getRemoved();

String getCustomLabelsPath();

String getLoginBaseDomain();
}
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 Down Expand Up @@ -77,6 +80,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 @@ -142,6 +163,11 @@ public Date getRemoved() {
return removed;
}

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

@Override
public String getLoginBaseDomain() {
return loginBaseDomain;
Expand Down
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 @@ -74,12 +77,12 @@ public GuiThemeVO() {

}

public GuiThemeVO(String name, String description, String css, String jsonConfiguration, boolean recursiveDomains,
boolean isPublic, Date created, String loginBaseDomain, Date removed) {
public GuiThemeVO(String name, String description, String css, String jsonConfiguration, String customLabelsPath, boolean recursiveDomains, boolean isPublic, Date created, String loginBaseDomain, 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 @@ -118,6 +121,10 @@ public String getJsonConfiguration() {
}

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

public Date getCreated() {
return created;
}
Expand Down Expand Up @@ -163,6 +170,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 @@ -145,3 +145,6 @@ CREATE TABLE IF NOT EXISTS `cloud`.`vmware_cbt_migration_cycle` (
UNIQUE KEY `uc_vmware_cbt_migration_cycle__migration_id__cycle_number` (`migration_id`, `cycle_number`),
INDEX `i_vmware_cbt_migration_cycle__migration_id` (`migration_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 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`,
`cloud`.`gui_themes`.`login_base_domain` AS `login_base_domain`,
(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,
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 @@ -5761,6 +5761,7 @@ public GuiThemeResponse createGuiThemeResponse(GuiThemeJoin guiThemeJoin) {
}

guiThemeResponse.setJsonConfiguration(guiThemeJoin.getJsonConfiguration());
guiThemeResponse.setCustomLabelsPath(guiThemeJoin.getCustomLabelsPath());
guiThemeResponse.setCss(guiThemeJoin.getCss());
guiThemeResponse.setLoginBaseDomain(guiThemeJoin.getLoginBaseDomain());
guiThemeResponse.setResponseName("guithemes");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,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 @@ -138,7 +139,7 @@ public GuiThemeJoin createGuiTheme(CreateGuiThemeCmd cmd) {
isPublic = false;
}

GuiThemeVO guiThemeVO = new GuiThemeVO(name, description, css, jsonConfiguration, recursiveDomains, isPublic, new Date(), cmd.getLoginBaseDomain(), null);
GuiThemeVO guiThemeVO = new GuiThemeVO(name, description, css, jsonConfiguration, customLabelsPath, recursiveDomains, isPublic, new Date(), cmd.getLoginBaseDomain(), null);
guiThemeDao.persist(guiThemeVO);
persistGuiThemeDetails(guiThemeVO.getId(), commonNames, providedDomainIds, providedAccountIds);
return guiThemeJoinDao.findById(guiThemeVO.getId());
Expand Down Expand Up @@ -273,6 +274,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 @@ -289,10 +291,10 @@ public GuiThemeJoin updateGuiTheme(UpdateGuiThemeCmd cmd) {
isPublic = false;
}

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

protected GuiThemeJoinVO persistGuiTheme(Long guiThemeId, String name, String description, String css, String jsonConfiguration, String commonNames, String providedDomainIds,
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, String loginBaseDomain){
return Transaction.execute((TransactionCallback<GuiThemeJoinVO>) status -> {
GuiThemeVO guiThemeVO = guiThemeDao.findById(guiThemeId);
Expand All @@ -313,6 +315,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
13 changes: 13 additions & 0 deletions ui/src/locales/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { vueProps } from '@/vue-app'
const FALLBACK_LANG = 'en'
const loadedLanguage = []
const messages = {}
let systemLang

export const i18n = createI18n({
locale: FALLBACK_LANG,
Expand All @@ -47,6 +48,17 @@ function fetchLocale (lang) {
.then(json => applyMessages(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]
})
})
}

export function loadLanguageAsync (lang) {
if (!lang) {
const locale = vueProps.$localStorage.get('LOCALE')
Expand All @@ -67,5 +79,6 @@ export function loadLanguageAsync (lang) {
// already has the translations and avoids a flash of raw keys.
return ensureTarget.then(() => {
i18n.global.locale = lang
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)
}

vueProps.$config.loginBaseDomain = ''
if (response?.loginbasedomain) {
vueProps.$config.loginBaseDomain = response.loginbasedomain
Expand Down
Loading