mirror of
https://github.com/jumpserver/lina.git
synced 2026-01-15 14:24:39 +00:00
perf: update page height
This commit is contained in:
@@ -360,6 +360,8 @@ $color-drop-menu-border: #e4e7ed;
|
||||
}
|
||||
|
||||
.el-dropdown-menu__item {
|
||||
padding: 0 20px;
|
||||
|
||||
&.is-disabled {
|
||||
color: var(--color-disabled);
|
||||
cursor: not-allowed;
|
||||
|
||||
108
src/components/Form/FormFields/DateRangePicker.vue
Normal file
108
src/components/Form/FormFields/DateRangePicker.vue
Normal file
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<el-date-picker
|
||||
v-model="value"
|
||||
:clearable="false"
|
||||
:default-time="['00:00:01', '23:59:59']"
|
||||
:end-placeholder="$tc('DateEnd')"
|
||||
:picker-options="pickerOptions"
|
||||
:range-separator="$tc('To')"
|
||||
:start-placeholder="$tc('DateStart')"
|
||||
class="datepicker"
|
||||
size="small"
|
||||
type="datetimerange"
|
||||
v-bind="$attrs"
|
||||
@change="handleDateChange"
|
||||
v-on="$listeners"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DatetimeRangePicker',
|
||||
components: {},
|
||||
props: {
|
||||
dateStart: {
|
||||
type: [Number, String, Date],
|
||||
default: null
|
||||
},
|
||||
dateEnd: {
|
||||
type: [Number, String, Date],
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const startValue = this.dateStart || this.$route.query['date_start']
|
||||
const endValue = this.dateEnd || this.$route.query['date_end']
|
||||
const dateStart = new Date(startValue)
|
||||
const dateTo = new Date(endValue)
|
||||
return {
|
||||
value: [dateStart, dateTo],
|
||||
pickerOptions: {
|
||||
shortcuts: [
|
||||
{
|
||||
text: this.$t('DateLast24Hours'),
|
||||
onClick: (picker) => this.onShortcutClick(picker, 1)
|
||||
},
|
||||
{
|
||||
text: this.$t('DateLastWeek'),
|
||||
onClick: (picker) => this.onShortcutClick(picker, 7)
|
||||
}, {
|
||||
text: this.$t('DateLastMonth'),
|
||||
onClick: (picker) => this.onShortcutClick(picker, 30)
|
||||
}, {
|
||||
text: this.$t('DateLast3Months'),
|
||||
onClick: (picker) => this.onShortcutClick(picker, 90)
|
||||
}, {
|
||||
text: this.$t('DateLastHarfYear'),
|
||||
onClick: (picker) => this.onShortcutClick(picker, 183)
|
||||
}, {
|
||||
text: this.$t('DateLastYear'),
|
||||
onClick: (picker) => this.onShortcutClick(picker, 365)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$log.debug('Datetime range picker value: ', this.value)
|
||||
},
|
||||
methods: {
|
||||
handleDateChange(val) {
|
||||
if (val[0].getTime() && val[1].getTime()) {
|
||||
this.$log.debug('Date change: ', val)
|
||||
this.$emit('dateChange', val)
|
||||
}
|
||||
},
|
||||
onShortcutClick(picker, day) {
|
||||
const end = new Date()
|
||||
const start = new Date()
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * day)
|
||||
picker.$emit('pick', [start, end])
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
.datepicker {
|
||||
margin-left: 10px;
|
||||
width: 233px;
|
||||
border: 1px solid #dcdee2;
|
||||
border-radius: 2px;
|
||||
height: 28px;
|
||||
|
||||
::v-deep .el-range-separator,
|
||||
::v-deep .el-input__icon {
|
||||
line-height: 26px;
|
||||
color: var(--color-icon-primary) !important;
|
||||
}
|
||||
|
||||
::v-deep .el-range-input {
|
||||
color: var(--color-text-primary) !important;
|
||||
}
|
||||
|
||||
::v-deep .el-range-input {
|
||||
width: 49%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -7,9 +7,9 @@
|
||||
:picker-options="pickerOptions"
|
||||
:range-separator="$tc('To')"
|
||||
:start-placeholder="$tc('DateStart')"
|
||||
:type="type"
|
||||
class="datepicker"
|
||||
size="small"
|
||||
type="datetimerange"
|
||||
v-bind="$attrs"
|
||||
@change="handleDateChange"
|
||||
v-on="$listeners"
|
||||
@@ -28,6 +28,15 @@ export default {
|
||||
dateEnd: {
|
||||
type: [Number, String, Date],
|
||||
default: null
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'daterange'
|
||||
// default: 'datetimerange'
|
||||
},
|
||||
toMinMax: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -35,6 +44,10 @@ export default {
|
||||
const endValue = this.dateEnd || this.$route.query['date_end']
|
||||
const dateStart = new Date(startValue)
|
||||
const dateTo = new Date(endValue)
|
||||
if (this.toMinMax) {
|
||||
dateStart.setHours(0, 0, 0, 0)
|
||||
dateTo.setHours(23, 59, 59, 999)
|
||||
}
|
||||
return {
|
||||
value: [dateStart, dateTo],
|
||||
pickerOptions: {
|
||||
@@ -74,9 +87,13 @@ export default {
|
||||
}
|
||||
},
|
||||
onShortcutClick(picker, day) {
|
||||
const end = new Date()
|
||||
const start = new Date()
|
||||
let start = new Date()
|
||||
let end = new Date()
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * day)
|
||||
if (this.toMinMax) {
|
||||
start = new Date(start.setHours(0, 0, 0, 0))
|
||||
end = new Date(end.setHours(23, 59, 59, 999))
|
||||
}
|
||||
picker.$emit('pick', [start, end])
|
||||
}
|
||||
}
|
||||
@@ -85,8 +102,11 @@ export default {
|
||||
|
||||
<style lang='scss' scoped>
|
||||
.datepicker {
|
||||
&.el-date-editor--daterange.el-input__inner {
|
||||
width: 243px;
|
||||
}
|
||||
|
||||
margin-left: 10px;
|
||||
width: 233px;
|
||||
border: 1px solid #dcdee2;
|
||||
border-radius: 2px;
|
||||
height: 28px;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div :class="{'no-title': title === 'null'}" class="page">
|
||||
<TagsView />
|
||||
<PageHeading v-if="iTitle || helpMessage" :help-msg="helpMessage" class="disabled-when-print">
|
||||
<PageHeading v-if="iTitle || helpMessage" :help-msg="helpMessage" class="disabled-when-print page-head">
|
||||
<el-button
|
||||
v-if="!inDrawer"
|
||||
:disabled="gobackDisabled"
|
||||
@@ -30,12 +30,10 @@
|
||||
</template>
|
||||
</PageHeading>
|
||||
<PageContent class="page-content">
|
||||
<div>
|
||||
<el-alert v-if="helpMessage" type="success">
|
||||
<span v-sanitize="helpMessage" class="announcement-main" />
|
||||
</el-alert>
|
||||
<slot />
|
||||
</div>
|
||||
<el-alert v-if="helpMessage" type="success">
|
||||
<span v-sanitize="helpMessage" class="announcement-main" />
|
||||
</el-alert>
|
||||
<slot />
|
||||
</PageContent>
|
||||
<UserConfirmDialog />
|
||||
</div>
|
||||
@@ -122,7 +120,10 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
height: calc(100vh - 65px);
|
||||
// 这个不加的话,page title 也会滚动
|
||||
height: calc(100vh - 52px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
|
||||
@@ -131,13 +132,22 @@ export default {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
&.no-title {
|
||||
}
|
||||
|
||||
.page-head {
|
||||
|
||||
}
|
||||
|
||||
.page-content {
|
||||
height: calc(100% - 20px);
|
||||
flex: 1; /* 占用剩余高度 */
|
||||
//height: calc(100% - 50px);
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto !important;
|
||||
|
||||
::v-deep > div {
|
||||
margin-bottom: 50px;
|
||||
// 这个当时为什么设置的
|
||||
//margin-bottom: 50px;
|
||||
// 别设置,用户列页面会被撑开
|
||||
//height: 100%;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<Page v-if="!loading" class="tab-page" v-bind="$attrs">
|
||||
<Page v-if="!loading" :title="title" class="tab-page" v-bind="$attrs">
|
||||
<template #headingRightSide>
|
||||
<slot name="headingRightSide" />
|
||||
</template>
|
||||
|
||||
<div style="height: 100%">
|
||||
<div class="tab-page-wrapper">
|
||||
<el-tabs
|
||||
v-if="tabIndices.length > 1"
|
||||
slot="submenu"
|
||||
@@ -80,6 +80,10 @@ export default {
|
||||
helpMessage: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -95,6 +99,7 @@ export default {
|
||||
return this.activeTab
|
||||
},
|
||||
set(item) {
|
||||
console.log('SEt active tab', item)
|
||||
this.activeTab = item
|
||||
this.$emit('update:activeMenu', item)
|
||||
}
|
||||
@@ -120,15 +125,6 @@ export default {
|
||||
return needActiveComponent
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route(to, from) {
|
||||
// 好像没必要
|
||||
// const activeTab = to.query?.tab
|
||||
// if (activeTab && this.iActiveMenu !== activeTab) {
|
||||
// this.iActiveMenu = activeTab
|
||||
// }
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.iActiveMenu = this.getPropActiveTab()
|
||||
this.loading = false
|
||||
@@ -167,6 +163,25 @@ export default {
|
||||
|
||||
<style lang='scss' scoped>
|
||||
|
||||
.page.no-title {
|
||||
::v-deep {
|
||||
.page-submenu .el-tabs__header {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.page-content > div {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.page-content {
|
||||
height: calc(100% - 15px);
|
||||
}
|
||||
|
||||
.tab-page-content {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page-submenu ::v-deep .el-tabs__header {
|
||||
background-color: white;
|
||||
margin-top: -10px;
|
||||
@@ -197,6 +212,10 @@ export default {
|
||||
}
|
||||
|
||||
.tab-page {
|
||||
.tab-page-wrapper {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
::v-deep .page-heading {
|
||||
border-bottom: none;
|
||||
}
|
||||
@@ -209,7 +228,7 @@ export default {
|
||||
.tab-page-content {
|
||||
padding: 10px 30px 22px;
|
||||
overflow-y: auto;
|
||||
height: calc(100vh - 130px);
|
||||
height: calc(100% - 30px);
|
||||
|
||||
.el-alert {
|
||||
margin-top: 0;
|
||||
|
||||
@@ -6,7 +6,8 @@ const state = {
|
||||
assetCategoriesDropdown: [],
|
||||
assetCategoriesCascader: [],
|
||||
platforms: [],
|
||||
platformGetting: false
|
||||
platformGetting: false,
|
||||
recentPlatformIds: JSON.parse(localStorage.getItem('recentPlatforms')) || []
|
||||
}
|
||||
|
||||
let isFetchingPlatforms = false
|
||||
@@ -89,8 +90,17 @@ const actions = {
|
||||
})
|
||||
})
|
||||
},
|
||||
addToRecentPlatforms({ commit, display, state }, platform) {
|
||||
const recentPlatformIds = state.recentPlatformIds.filter(i => i !== platform.id)
|
||||
recentPlatformIds.unshift(platform.id)
|
||||
if (recentPlatformIds.length > 8) {
|
||||
recentPlatformIds.pop()
|
||||
}
|
||||
state.recentPlatformIds = recentPlatformIds
|
||||
localStorage.setItem('recentPlatforms', JSON.stringify(recentPlatformIds))
|
||||
},
|
||||
getRecentPlatforms({ commit, dispatch, state }) {
|
||||
const recentPlatformIds = JSON.parse(localStorage.getItem('recentPlatforms')) || []
|
||||
const recentPlatformIds = state.recentPlatformIds
|
||||
return new Promise(resolve => {
|
||||
dispatch('getPlatforms').then(platforms => {
|
||||
resolve(platforms.filter(p => recentPlatformIds.includes(p.id)))
|
||||
|
||||
@@ -6,26 +6,20 @@
|
||||
import BaseAssetCreateUpdate from './BaseAssetCreateUpdate'
|
||||
import { UploadKey } from '@/components'
|
||||
import rules from '@/components/Form/DataForm/rules'
|
||||
import { setUrlParam } from '@/utils/common'
|
||||
|
||||
export default {
|
||||
name: 'DatabaseCreateUpdate',
|
||||
components: { BaseAssetCreateUpdate },
|
||||
data() {
|
||||
return {
|
||||
url: '/api/v1/assets/databases/',
|
||||
url: `/api/v1/assets/databases/?platform=${this.$route.query.platform}`,
|
||||
addFields: this.getAddFields(),
|
||||
addFieldsMeta: this.getAddFieldsMeta()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.$route.query._platform) {
|
||||
this.url = setUrlParam(this.url, 'platform', this.$route.query._platform)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getAddFields() {
|
||||
const platform = this.$route.query._type
|
||||
const platform = this.$route.query.type
|
||||
const baseFields = [[this.$t('Basic'), ['db_name']]]
|
||||
let tlsFields = ['use_ssl', 'ca_cert']
|
||||
const platformFieldsMap = {
|
||||
@@ -47,7 +41,7 @@ export default {
|
||||
return baseFields
|
||||
},
|
||||
getAddFieldsMeta() {
|
||||
const platform = this.$route.query._type
|
||||
const platform = this.$route.query.type
|
||||
const fieldsMeta = {
|
||||
db_name: {
|
||||
label: this.$t('DefaultDatabase')
|
||||
|
||||
@@ -223,14 +223,9 @@ export default {
|
||||
category: platform.category.value,
|
||||
node: this.$route.query?.node || this.$route.query?.node_id || ''
|
||||
}
|
||||
this.$router.push({
|
||||
query: {
|
||||
_platform: createProps.platform,
|
||||
_type: createProps.type,
|
||||
_category: createProps.category,
|
||||
_node: createProps.node
|
||||
}
|
||||
})
|
||||
for (const key in createProps) {
|
||||
this.$route.query[key] = createProps[key]
|
||||
}
|
||||
this.$store.dispatch('common/setDrawerActionMeta', {
|
||||
action: 'create',
|
||||
...createProps
|
||||
|
||||
@@ -124,8 +124,8 @@ export default {
|
||||
this.initial.su_method = this.suMethodLimits[0]
|
||||
},
|
||||
async setCategories() {
|
||||
const category = this.$route.query._category
|
||||
const type = this.$route.query._type
|
||||
const category = this.$route.query.category
|
||||
const type = this.$route.query.type
|
||||
const state = await this.$store.dispatch('assets/getAssetCategories')
|
||||
this.fieldsMeta.category_type.el.options = state.assetCategoriesCascader
|
||||
if (category && type) {
|
||||
@@ -135,8 +135,8 @@ export default {
|
||||
return new Promise((resolve, reject) => resolve(true))
|
||||
},
|
||||
async setConstraints() {
|
||||
const category = this.$route.query._category
|
||||
const type = this.$route.query._type
|
||||
const category = this.$route.query.category
|
||||
const type = this.$route.query.type
|
||||
const url = `/api/v1/assets/categories/constraints/?category=${category}&type=${type}`
|
||||
const constraints = await this.$axios.get(url)
|
||||
this.defaultOptions = constraints
|
||||
|
||||
@@ -104,9 +104,8 @@ export default {
|
||||
canUpdate: ({ row }) => !row.internal && vm.$hasPerm('assets.change_platform'),
|
||||
canDelete: ({ row }) => !row.internal && vm.$hasPerm('assets.delete_platform'),
|
||||
onUpdate({ row, col }) {
|
||||
vm.$router.push({
|
||||
query: { _type: row.type.value, _category: row.category.value }
|
||||
})
|
||||
vm.$route.query.type = row.type.value
|
||||
vm.$route.query.category = row.category.value
|
||||
vm.$refs.genericListTable.onUpdate({ row, col })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<TabPage
|
||||
:active-menu.sync="activeMenu"
|
||||
:submenu="tab.submenu"
|
||||
title="null"
|
||||
/>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user