mirror of
https://github.com/jumpserver/lina.git
synced 2025-09-25 14:25:23 +00:00
Merge branch 'pr@pam@update_panel' into pam
This commit is contained in:
@@ -1,72 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="panel-item">
|
|
||||||
<span class="item-label">{{ title }}: </span>
|
|
||||||
<span :title="content" class="text-info">{{ content || '' }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'InfoPanel',
|
|
||||||
components: {},
|
|
||||||
props: {
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: () => ''
|
|
||||||
},
|
|
||||||
content: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: () => ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {}
|
|
||||||
},
|
|
||||||
methods: {}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang='scss' scoped>
|
|
||||||
@mixin textOverflow {
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-item {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
text-align: left;
|
|
||||||
padding: 3px 0;
|
|
||||||
line-height: 20px;
|
|
||||||
|
|
||||||
.item-label {
|
|
||||||
text-align: left;
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
min-width: 110px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-info {
|
|
||||||
flex: 2;
|
|
||||||
@include textOverflow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
html:lang(en) .panel-item span {
|
|
||||||
min-width: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
html:lang(ja) .panel-item span {
|
|
||||||
min-width: 160px;
|
|
||||||
}
|
|
||||||
|
|
||||||
html:lang(cn) .panel-item span {
|
|
||||||
min-width: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
html:lang(zh_hant) .panel-item span {
|
|
||||||
min-width: 120px;
|
|
||||||
}
|
|
||||||
</style>
|
|
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div @click="handleClick">
|
||||||
<span v-if="d.edition === 'enterprise'" class="enterprise">
|
<span v-if="d.edition === 'enterprise'" class="enterprise">
|
||||||
{{ $t('Enterprise') }}
|
{{ $t('Enterprise') }}
|
||||||
</span>
|
</span>
|
||||||
@@ -50,6 +50,9 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
capitalize(str) {
|
capitalize(str) {
|
||||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||||
|
},
|
||||||
|
handleClick() {
|
||||||
|
this.$emit('onClick', this.d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,15 +14,13 @@
|
|||||||
<el-card
|
<el-card
|
||||||
v-for="(d, index) in totalData"
|
v-for="(d, index) in totalData"
|
||||||
:key="index"
|
:key="index"
|
||||||
:body-style="{ 'text-align': 'center', 'padding': '15px' }"
|
|
||||||
:class="{'is-disabled': isDisabled(d)}"
|
:class="{'is-disabled': isDisabled(d)}"
|
||||||
class="my-card"
|
class="the-card"
|
||||||
shadow="hover"
|
shadow="hover"
|
||||||
@click.native="onView(d)"
|
|
||||||
>
|
>
|
||||||
<keep-alive>
|
<keep-alive>
|
||||||
<slot :index="index" :item="d">
|
<slot :index="index" :item="d" :onView="onView">
|
||||||
<Panel :d="d" />
|
<Panel :d="d" @click.native="onView(d)" />
|
||||||
</slot>
|
</slot>
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</el-card>
|
</el-card>
|
||||||
@@ -230,15 +228,18 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
|
|
||||||
.my-card {
|
.the-card {
|
||||||
min-width: 330px;
|
min-width: 330px;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
height: 230px;
|
height: 230px;
|
||||||
width: 380px;
|
width: 380px;
|
||||||
|
padding: 15px;
|
||||||
|
|
||||||
::v-deep .el-card__body {
|
::v-deep .el-card__body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-disabled {
|
&.is-disabled {
|
||||||
|
67
src/components/Table/InfoCardTable/Info.vue
Normal file
67
src/components/Table/InfoCardTable/Info.vue
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<div class="item-info">
|
||||||
|
<el-row>
|
||||||
|
<el-col v-for="item of infos" :key="item.content" :span="12" class="panel-item">
|
||||||
|
<small class="item-label">{{ item.title }}:</small>
|
||||||
|
<h4 class="item-value">{{ item.content }}</h4>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'InfoPanel',
|
||||||
|
components: {},
|
||||||
|
props: {
|
||||||
|
infos: {
|
||||||
|
type: Array,
|
||||||
|
default: () => ([])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
console.log('INfo: ', this.infos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang='scss' scoped>
|
||||||
|
@mixin textOverflow {
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-item {
|
||||||
|
text-align: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-label {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//.panel-item {
|
||||||
|
// flex-wrap: nowrap;
|
||||||
|
// text-align: left;
|
||||||
|
// padding: 3px 0;
|
||||||
|
// line-height: 20px;
|
||||||
|
//
|
||||||
|
// .item-label {
|
||||||
|
// text-align: left;
|
||||||
|
// display: flex;
|
||||||
|
// flex: 1;
|
||||||
|
// min-width: 110px;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// .text-info {
|
||||||
|
// flex: 2;
|
||||||
|
// @include textOverflow;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
|
||||||
|
</style>
|
@@ -1,16 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="account-panel">
|
<div class="info-panel">
|
||||||
<el-row :gutter="20">
|
<div class="panel-header">
|
||||||
<el-col :span="21">
|
<div class="panel-title">
|
||||||
<div class="title">
|
<el-avatar :src="imageUrl" />
|
||||||
<span>{{ object.name }}</span>
|
<span>{{ object.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
<div
|
||||||
<el-col v-if="iActions.length !== 0" :span="3" @click.native="handleClick($event)">
|
v-if="iActions.length !== 0"
|
||||||
|
class="panel-actions"
|
||||||
|
@click="handleClick($event)"
|
||||||
|
>
|
||||||
<el-dropdown>
|
<el-dropdown>
|
||||||
<el-link :underline="false" type="primary">
|
<el-button size="mini">
|
||||||
<i class="el-icon-more el-icon--right" style="color: var(--color-text-primary)" />
|
<i class="el-icon-more el-icon--right" />
|
||||||
</el-link>
|
</el-button>
|
||||||
<el-dropdown-menu default="dropdown">
|
<el-dropdown-menu default="dropdown">
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
v-for="action in iActions"
|
v-for="action in iActions"
|
||||||
@@ -18,30 +21,21 @@
|
|||||||
:disabled="action.disabled"
|
:disabled="action.disabled"
|
||||||
@click.native="action.callback(object)"
|
@click.native="action.callback(object)"
|
||||||
>
|
>
|
||||||
<i v-if="action.icon" :class="action.icon" /> {{ action.name }}
|
{{ action.name }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
</div>
|
||||||
<el-row :gutter="20" class="panel-content">
|
<div class="panel-content" @click="gotoDetail">
|
||||||
<el-col :span="6" class="panel-image">
|
<InfoPanel :infos="getInfos(object)" />
|
||||||
<el-image :src="imageUrl" fit="contain" />
|
</div>
|
||||||
</el-col>
|
<el-row class="panel-footer" />
|
||||||
<el-col :span="18" class="panel-info">
|
|
||||||
<InfoPanel
|
|
||||||
v-for="(obj, index) in getInfos(object)"
|
|
||||||
:key="index"
|
|
||||||
:content="obj.content"
|
|
||||||
:title="obj.title"
|
|
||||||
/>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import InfoPanel from './InfoPanel'
|
import InfoPanel from './Info.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CardPanel',
|
name: 'CardPanel',
|
||||||
@@ -77,6 +71,11 @@ export default {
|
|||||||
type: Function,
|
type: Function,
|
||||||
default: () => {
|
default: () => {
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onView: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -120,6 +119,9 @@ export default {
|
|||||||
const resource = this.tableConfig.permissions?.resource
|
const resource = this.tableConfig.permissions?.resource
|
||||||
return !this.$hasPerm(`${app}.${action}_${resource}`)
|
return !this.$hasPerm(`${app}.${action}_${resource}`)
|
||||||
},
|
},
|
||||||
|
gotoDetail() {
|
||||||
|
this.onView(this.object)
|
||||||
|
},
|
||||||
handleClick(event) {
|
handleClick(event) {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
},
|
},
|
||||||
@@ -145,29 +147,54 @@ export default {
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
.account-panel {
|
.info-panel {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
//height: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
.title {
|
.panel-header {
|
||||||
text-align: left;
|
padding: 5px 10px;
|
||||||
|
border-bottom: solid 1px #e7eaec;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
|
cursor: default;
|
||||||
|
|
||||||
|
.panel-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
::v-deep {
|
||||||
text-overflow: ellipsis;
|
.el-avatar {
|
||||||
font-size: 1.1em;
|
background: white;
|
||||||
color: #555555;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
::v-deep {
|
||||||
|
button.el-button--mini {
|
||||||
|
padding: 5px 7px;
|
||||||
|
|
||||||
|
.el-icon--right {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-content {
|
.panel-content {
|
||||||
display: flex;
|
display: block;
|
||||||
height: 100px;
|
padding: 10px 30px;
|
||||||
padding: 10px 0;
|
cursor: pointer;
|
||||||
|
|
||||||
.panel-image {
|
.panel-image {
|
||||||
margin: auto 5px;
|
margin: auto 5px;
|
||||||
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-info {
|
.panel-info {
|
@@ -3,11 +3,14 @@
|
|||||||
ref="table"
|
ref="table"
|
||||||
:columns="3"
|
:columns="3"
|
||||||
:table-config="tableConfig"
|
:table-config="tableConfig"
|
||||||
|
class="info-card-table"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
v-on="$listeners"
|
||||||
>
|
>
|
||||||
<template v-slot:default="slotProps">
|
<template v-slot:default="slotProps">
|
||||||
<CardPanel
|
<CardPanel
|
||||||
:object="slotProps.item"
|
:object="slotProps.item"
|
||||||
|
:on-view="slotProps.onView"
|
||||||
:table-config="tableConfig"
|
:table-config="tableConfig"
|
||||||
v-bind="subComponentProps"
|
v-bind="subComponentProps"
|
||||||
@refresh="reloadTable"
|
@refresh="reloadTable"
|
||||||
@@ -18,7 +21,7 @@
|
|||||||
|
|
||||||
<script type="text/jsx">
|
<script type="text/jsx">
|
||||||
import CardTable from '@/components/Table/CardTable/index.vue'
|
import CardTable from '@/components/Table/CardTable/index.vue'
|
||||||
import CardPanel from './CardPanel.vue'
|
import CardPanel from './Panel.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SmallCard',
|
name: 'SmallCard',
|
||||||
@@ -37,8 +40,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
reloadTable() {
|
reloadTable() {
|
||||||
@@ -47,3 +49,13 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.info-card-table {
|
||||||
|
::v-deep {
|
||||||
|
div.the-card {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@@ -24,7 +24,7 @@ import { lan, privateCloudProviders, publicCloudProviders } from '../const'
|
|||||||
import CreateDialog from './components/CreateDialog.vue'
|
import CreateDialog from './components/CreateDialog.vue'
|
||||||
import UpdateDialog from './components/UpdateDialog.vue'
|
import UpdateDialog from './components/UpdateDialog.vue'
|
||||||
import SyncDialog from './components/SyncDialog.vue'
|
import SyncDialog from './components/SyncDialog.vue'
|
||||||
import SmallCard from '@/components/Table/CardTable/DataCardTable/index.vue'
|
import SmallCard from '@/components/Table/InfoCardTable/index.vue'
|
||||||
import { ACCOUNT_PROVIDER_ATTRS_MAP } from '@/views/assets/Cloud/const'
|
import { ACCOUNT_PROVIDER_ATTRS_MAP } from '@/views/assets/Cloud/const'
|
||||||
import { toSafeLocalDateStr } from '@/utils/time'
|
import { toSafeLocalDateStr } from '@/utils/time'
|
||||||
|
|
||||||
@@ -186,12 +186,4 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
.account-table {
|
|
||||||
::v-deep {
|
|
||||||
.panel-content {
|
|
||||||
padding: 30px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
Reference in New Issue
Block a user