Merge branch 'pr@pam@update_panel' into pam

This commit is contained in:
ibuler
2025-03-10 14:25:54 +08:00
7 changed files with 163 additions and 133 deletions

View File

@@ -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>

View File

@@ -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)
} }
} }
} }

View File

@@ -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 {

View 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>

View File

@@ -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;
font-weight: 600; border-bottom: solid 1px #e7eaec;
white-space: nowrap; display: flex;
overflow: hidden; justify-content: space-between;
text-overflow: ellipsis; gap: 10px;
font-size: 1.1em; cursor: default;
color: #555555;
.panel-title {
display: flex;
align-items: center;
font-weight: 600;
::v-deep {
.el-avatar {
background: white;
}
}
}
.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 {

View File

@@ -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>

View File

@@ -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>