DdataeaseShufix: 样式优化
b9dae819创建于 11 天前历史提交
<script setup lang="ts">
import icon_collection_outlined from '@/assets/svg/icon_collection_outlined.svg'
import visualStar from '@/assets/svg/visual-star.svg'
import dvInfoSvg from '@/assets/svg/dv-info.svg'
import dvHeadMore from '@/assets/svg/dv-head-more.svg'
import icon_pc_fullscreen from '@/assets/svg/icon_pc_fullscreen.svg'
import icon_pc_outlined from '@/assets/svg/icon_pc_outlined.svg'
import icon_download_outlined from '@/assets/svg/icon_download_outlined.svg'
import icon_replace_outlined from '@/assets/svg/icon_replace_outlined.svg'
import icon_edit_outlined from '@/assets/svg/icon_edit_outlined.svg'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { storeToRefs } from 'pinia'
import { useI18n } from '@/hooks/web/useI18n'
import { useAppStoreWithOut } from '@/store/modules/app'
import DvDetailInfo from '@/views/common/DvDetailInfo.vue'
import { useEmbedded } from '@/store/modules/embedded'
import { storeApi, storeStatusApi } from '@/api/visualization/dataVisualization'
import { ref, watch, computed } from 'vue'
import ShareVisualHead from '@/views/share/share/ShareVisualHead.vue'
import { XpackComponent } from '@/components/plugin'
import { useEmitt } from '@/hooks/web/useEmitt'
import { useShareStoreWithOut } from '@/store/modules/share'
import { exportPermission } from '@/utils/utils'
import { useCache } from '@/hooks/web/useCache'
import { isDesktop } from '@/utils/ModelUtil'

const shareStore = useShareStoreWithOut()
const { wsCache } = useCache('localStorage')
const dvMainStore = dvMainStoreWithOut()
const appStore = useAppStoreWithOut()
const { dvInfo } = storeToRefs(dvMainStore)
const emit = defineEmits(['reload', 'download', 'downloadAsAppTemplate'])
const { t } = useI18n()
const embeddedStore = useEmbedded()
const openType = wsCache.get('open-backend') === '1' ? '_self' : '_blank'
const favorited = ref(false)
const preview = () => {
  const baseUrl = isDataEaseBi.value ? embeddedStore.baseUrl : ''
  const url =
    baseUrl +
    '#/preview?dvId=' +
    dvInfo.value.id +
    '&dvType=' +
    dvInfo.value['type'] +
    '&ignoreParams=true'
  const newWindow = window.open(url, '_blank')
  initOpenHandler(newWindow)
}
const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
const isIframe = computed(() => appStore.getIsIframe)
const shareDisable = computed(() => shareStore.getShareDisable || isDesktop())
const exportPermissions = computed(() =>
  exportPermission(dvInfo.value['weight'], dvInfo.value['ext'])
)
const reload = () => {
  emit('reload', dvInfo.value.id)
}

const download = type => {
  emit('download', type)
}
const downloadAsAppTemplate = downloadType => {
  emit('downloadAsAppTemplate', downloadType)
}

const dvEdit = () => {
  if (isDataEaseBi.value || isIframe.value) {
    embeddedStore.clearState()
    if (dvInfo.value.type === 'dataV') {
      embeddedStore.setDvId(dvInfo.value.id)
    } else {
      embeddedStore.setResourceId(dvInfo.value.id)
    }
    useEmitt().emitter.emit(
      'changeCurrentComponent',
      dvInfo.value.type === 'dataV' ? 'VisualizationEditor' : 'DashboardEditor'
    )
    return
  }
  const baseUrl = dvInfo.value.type === 'dataV' ? '#/dvCanvas?dvId=' : '#/dashboard?resourceId='
  const newWindow = window.open(baseUrl + dvInfo.value.id, openType)
  initOpenHandler(newWindow)
}

const executeStore = () => {
  const param = {
    id: dvInfo.value.id,
    type: dvInfo.value.type === 'dashboard' ? 'panel' : 'screen'
  }
  storeApi(param).then(() => {
    storeQuery()
  })
}
const storeQuery = () => {
  if (!dvInfo?.value?.id) return
  storeStatusApi(dvInfo.value.id).then(res => {
    favorited.value = res.data
  })
}
storeQuery()
watch(
  () => dvInfo.value.id,
  () => {
    storeQuery()
  }
)

const openHandler = ref(null)
const initOpenHandler = newWindow => {
  if (openHandler?.value) {
    const pm = {
      methodName: 'initOpenHandler',
      args: newWindow
    }
    openHandler.value?.invokeMethod(pm)
  }
}
</script>

<template>
  <div class="preview-head flex-align-center">
    <div :title="dvInfo.name" class="canvas-name ellipsis">{{ dvInfo.name }}</div>
    <div v-show="dvInfo.status === 2" class="canvas-have-update">
      {{ t('visualization.publish_update_tips') }}
    </div>
    <el-tooltip
      effect="dark"
      :content="favorited ? t('visualization.cancel_store') : t('visualization.store')"
      placement="top"
    >
      <el-icon
        v-if="dvInfo.status !== 0"
        class="custom-icon hover-icon"
        @click="executeStore"
        :style="{ color: favorited ? '#FFC60A' : '#646A73' }"
      >
        <icon
          ><component
            class="svg-icon"
            :is="favorited ? visualStar : icon_collection_outlined"
          ></component
        ></icon>
      </el-icon>
    </el-tooltip>
    <el-divider style="margin: 0 16px 0 7px" direction="vertical" />
    <div class="create-area flex-align-center">
      <span style="line-height: 22px"
        >{{ t('visualization.creator') }}:{{ dvInfo.creatorName }}</span
      >
      <el-popover show-arrow :offset="8" placement="bottom" width="400" trigger="hover">
        <template #reference>
          <el-icon class="info-tips"
            ><Icon name="dv-info"><dvInfoSvg class="svg-icon" /></Icon
          ></el-icon>
        </template>
        <dv-detail-info></dv-detail-info>
      </el-popover>
    </div>
    <div class="canvas-opt-button">
      <el-button
        v-if="!isIframe"
        :disabled="dvInfo.status === 0"
        secondary
        @click="() => useEmitt().emitter.emit('canvasFullscreen')"
      >
        <template #icon>
          <icon name="icon_pc_fullscreen"><icon_pc_fullscreen class="svg-icon" /></icon>
        </template>
        {{ t('visualization.fullscreen') }}</el-button
      >
      <el-button secondary @click="preview()" :disabled="dvInfo.status === 0">
        <template #icon>
          <icon name="icon_pc_outlined"><icon_pc_outlined class="svg-icon" /></icon>
        </template>
        {{ t('template_manage.preview') }}
      </el-button>
      <ShareVisualHead
        v-if="!shareDisable"
        :disabled="dvInfo.status === 0"
        :resource-id="dvInfo.id"
        :weight="dvInfo.weight"
        :resource-type="dvInfo.type"
      />
      <el-button class="custom-button" v-if="dvInfo.weight > 6" type="primary" @click="dvEdit()">
        <template #icon>
          <icon name="icon_edit_outlined"><icon_edit_outlined class="svg-icon" /></icon>
        </template>
        {{ t('visualization.edit') }}</el-button
      >
      <el-dropdown :disabled="dvInfo.status === 0" popper-class="pad12" trigger="click">
        <el-icon class="head-more-icon">
          <Icon name="dv-head-more"><dvHeadMore class="svg-icon" /></Icon>
        </el-icon>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item @click="reload()"
              ><el-icon color="#646A73" size="16"><icon_replace_outlined /></el-icon
              >{{ t('visualization.refresh_data') }}
            </el-dropdown-item>
            <el-dropdown
              style="width: 100%; overflow: hidden"
              trigger="hover"
              popper-class="pad12"
              placement="left-start"
              v-if="exportPermissions[0]"
            >
              <div class="ed-dropdown-menu__item flex-align-center icon">
                <el-icon color="#646A73" size="16"><icon_download_outlined /></el-icon>
                {{ t('visualization.export_as') }}
                <el-icon color="#646A73" size="16" class="arrow-right_icon"><ArrowRight /></el-icon>
              </div>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item @click="download('pdf')">PDF</el-dropdown-item>
                  <el-dropdown-item @click="downloadAsAppTemplate('template')">{{
                    t('visualization.style_template')
                  }}</el-dropdown-item>
                  <el-dropdown-item @click="downloadAsAppTemplate('app')">{{
                    t('visualization.apply_template')
                  }}</el-dropdown-item>
                  <el-dropdown-item @click="download('img')">{{
                    t('chart.image')
                  }}</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
    </div>
  </div>
  <XpackComponent ref="openHandler" jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvT3BlbkhhbmRsZXI=" />
</template>

<style lang="less">
.pad12 {
  .ed-dropdown-menu__item {
    padding: 5px 36px 5px 12px !important;

    .ed-icon {
      margin-right: 8px;
    }
    .arrow-right_icon {
      position: absolute;
      right: 12px;
      margin-right: 0;
    }

    &:has(.arrow-right_icon) {
      width: 100%;
    }
  }
}
.preview-head {
  width: 100%;
  min-width: 300px;
  height: 56px;
  padding: 16px 24px;
  border-bottom: 1px solid rgba(31, 35, 41, 0.15);
  .canvas-name {
    max-width: 400px;
    font-size: 16px;
    font-weight: 500;
  }
  .canvas-have-update {
    background-color: rgba(52, 199, 36, 0.2);
    color: rgba(44, 169, 31, 1);
    font-weight: 400;
    font-size: 12px;
    line-height: 20px;
    vertical-align: middle;
    padding: 0 4px;
    margin-left: 8px;
  }
  .custom-icon {
    cursor: pointer;
    margin-left: 8px;
  }
  .create-area {
    color: #646a73;
    font-weight: 400;
    font-size: 14px;
  }
  .canvas-opt-button {
    display: flex;
    justify-content: right;
    align-items: center;
    flex: 1;
    .head-more-icon {
      color: #1f2329;
      margin-left: 12px;
      cursor: pointer;
      font-size: 20px;
      border-radius: 6px;
      position: relative;
      &:hover {
        &::after {
          content: '';
          position: absolute;
          top: -4px;
          left: -4px;
          border-radius: 6px;
          height: 28px;
          width: 28px;
          background: #1f23291a;
        }
      }
    }
  }
}
.info-tips {
  margin-left: 4px;
  font-size: 16px;
  color: #646a73;
}

.custom-button {
  margin-left: 12px;
}
</style>