This is an automated email from the ASF dual-hosted git repository. DaanHoogland pushed a commit to branch 4.22 in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit cdd03d78748f8f30cafbd2b7dbca65c5cb9c4041 Merge: 2e63c601fc2 4b2d387287a Author: Daan Hoogland <[email protected]> AuthorDate: Mon Oct 5 16:27:34 2026 +0200 Merge branch '4.20' into 4.22 .../org/apache/cloudstack/backup/BackupVO.java | 2 +- .../java/com/cloud/utils/db/GenericDaoBase.java | 78 +++++++---- .../com/cloud/utils/db/GenericDaoBaseTest.java | 75 +++++++++++ .../wrapper/LibvirtPlugNicCommandWrapper.java | 105 +++++++++++++++ .../kvm/resource/LibvirtComputingResourceTest.java | 9 ++ .../wrapper/LibvirtPlugNicCommandWrapperTest.java | 147 +++++++++++++++++++++ server/src/main/java/com/cloud/api/ApiServer.java | 7 +- .../com/cloud/network/IpAddressManagerImpl.java | 2 +- .../src/test/java/com/cloud/api/ApiServerTest.java | 69 ++++++++++ .../network/IpAddressManagerImplSourceNatTest.java | 58 ++++++++ ui/src/components/view/InfoCard.vue | 12 +- ui/src/store/modules/user.js | 136 ++++++++----------- ui/src/utils/links.js | 72 ++++++++++ utils/src/main/java/com/cloud/utils/DateUtil.java | 63 ++++----- .../test/java/com/cloud/utils/DateUtilTest.java | 113 ++++++++++++++-- 15 files changed, 782 insertions(+), 166 deletions(-) diff --cc engine/schema/src/main/java/org/apache/cloudstack/backup/BackupVO.java index a17f7633690,a11de51ed63..39a7fd2b2ea --- a/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupVO.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupVO.java @@@ -66,10 -57,10 +66,10 @@@ public class BackupVO implements Backu private String externalId; @Column(name = "type") - private String backupType; + private String type; @Column(name = "date") - @Temporal(value = TemporalType.DATE) + @Temporal(value = TemporalType.TIMESTAMP) private Date date; @Column(name = GenericDao.REMOVED_COLUMN) diff --cc ui/src/components/view/InfoCard.vue index e37c8af3d6e,34c29923123..51f182b6f61 --- a/ui/src/components/view/InfoCard.vue +++ b/ui/src/components/view/InfoCard.vue @@@ -607,17 -558,19 +607,19 @@@ <div class="resource-detail-item" v-if="resource.templateid"> <div class="resource-detail-item__label">{{ resource.templateformat === 'ISO'? $t('label.iso') : $t('label.templatename') }}</div> <div class="resource-detail-item__details"> - <resource-icon v-if="resource.icon" :image="getImage(resource.icon.base64image)" size="1x" style="margin-right: 5px"/> + <resource-icon v-if="images.template || images.guestoscategory" :image="images.template || images.guestoscategory" size="1x" style="margin-right: 5px"/> <SaveOutlined v-else /> - <router-link :to="{ path: (resource.templateformat === 'ISO' ? '/iso/' : '/template/') + resource.templateid }">{{ resource.templatedisplaytext || resource.templatename || resource.templateid }} </router-link> + <router-link v-if="validLinks.template" :to="{ path: (resource.templateformat === 'ISO' ? '/iso/' : '/template/') + resource.templateid }">{{ resource.templatedisplaytext || resource.templatename || resource.templateid }} </router-link> + <span v-else>{{ resource.templatedisplaytext || resource.templatename || resource.templateid }}</span> </div> </div> <div class="resource-detail-item" v-if="resource.isoid"> <div class="resource-detail-item__label">{{ $t('label.isoname') }}</div> <div class="resource-detail-item__details"> - <resource-icon v-if="resource.icon" :image="getImage(resource.icon.base64image)" size="1x" style="margin-right: 5px"/> + <resource-icon v-if="images.iso || (resource.isoid === resource.templateid && images.guestoscategory)" :image="images.iso || images.guestoscategory" size="1x" style="margin-right: 5px"/> <UsbOutlined v-else /> - <router-link :to="{ path: '/iso/' + resource.isoid }">{{ resource.isodisplaytext || resource.isoname || resource.isoid }} </router-link> + <router-link v-if="validLinks.iso" :to="{ path: '/iso/' + resource.isoid }">{{ resource.isodisplaytext || resource.isoname || resource.isoid }} </router-link> + <span v-else>{{ resource.isodisplaytext || resource.isoname || resource.isoid }}</span> </div> </div> <div class="resource-detail-item" v-if="resource.serviceofferingname && resource.serviceofferingid"> @@@ -978,9 -881,9 +980,9 @@@ </template> <script> -import { api } from '@/api' +import { getAPI, postAPI } from '@/api' import { createPathBasedOnVmType } from '@/utils/plugins' - import { validateLinks } from '@/utils/links' + import { validateLinksAsync } from '@/utils/links' import Console from '@/components/widgets/Console' import OsLogo from '@/components/widgets/OsLogo' import Status from '@/components/widgets/Status' diff --cc ui/src/store/modules/user.js index 5c78b8a592f,eb3fdccb5e2..f9adc7b53c3 --- a/ui/src/store/modules/user.js +++ b/ui/src/store/modules/user.js @@@ -47,10 -46,51 +47,55 @@@ import LATEST_CS_VERSION } from '@/store/mutation-types' +import { + applyCustomGuiTheme +} from '@/utils/guiTheme' + + function setLoginCookies (result) { + Cookies.set('account', result.account) + Cookies.set('domainid', result.domainid) + Cookies.set('role', result.type) + Cookies.set('timezone', result.timezone) + Cookies.set('timezoneoffset', result.timezoneoffset) + Cookies.set('userfullname', result.firstname + ' ' + result.lastname) + Cookies.set('userid', result.userid) + Cookies.set('username', result.username) + } + + function processLoginResponse (commit, response) { + const result = response.loginresponse || {} + setLoginCookies(result) + vueProps.$localStorage.set(ACCESS_TOKEN, result.sessionkey, 24 * 60 * 60 * 1000) + commit('SET_TOKEN', result.sessionkey) + commit('SET_TIMEZONE_OFFSET', result.timezoneoffset) + + const cachedUseBrowserTimezone = vueProps.$localStorage.get(USE_BROWSER_TIMEZONE, false) + commit('SET_USE_BROWSER_TIMEZONE', cachedUseBrowserTimezone) + const darkMode = vueProps.$localStorage.get(DARK_MODE, false) + commit('SET_DARK_MODE', darkMode) + const cachedCustomColumns = vueProps.$localStorage.get(CUSTOM_COLUMNS, {}) + commit('SET_CUSTOM_COLUMNS', cachedCustomColumns) + + commit('SET_APIS', {}) + commit('SET_NAME', '') + commit('SET_AVATAR', '') + commit('SET_INFO', {}) + commit('SET_PROJECT', {}) + commit('SET_HEADER_NOTICES', []) + commit('SET_FEATURES', {}) + commit('SET_LDAP', {}) + commit('SET_CLOUDIAN', {}) + commit('SET_DOMAIN_STORE', {}) + commit('SET_LOGOUT_FLAG', false) + commit('SET_2FA_ENABLED', (result.is2faenabled === 'true')) + commit('SET_2FA_PROVIDER', result.providerfor2fa) + commit('SET_2FA_ISSUER', result.issuerfor2fa) + commit('SET_LOGIN_FLAG', false) + const latestVersion = vueProps.$localStorage.get(LATEST_CS_VERSION, { version: '', fetchedTs: 0 }) + commit('SET_LATEST_VERSION', latestVersion) + notification.destroy() + } + const user = { state: { token: '',
