index.vue 5.3 KB
<script lang="ts" setup>
  import { onMounted, unref } from 'vue';
  import { ref } from 'vue';
  import { Empty, Spin, Button } from 'ant-design-vue';
  import { getBoundingClientRect } from '/@/utils/domUtils';
  import { GridItem, GridLayout } from 'vue3-grid-layout';
  import {
    DEFAULT_MAX_COL,
    DEFAULT_MIN_HEIGHT,
    DEFAULT_MIN_WIDTH,
    DEFAULT_ITEM_MARIGN,
    VisualComponentPermission,
  } from './index';
  import { useDragGridLayout } from './hooks/useDragGridLayout';
  import { WidgetHeader, WidgetWrapper } from './components/WidgetWrapper';
  import { computed } from 'vue';
  import { WidgetDataType, useDataSource } from './hooks/useDataSource';
  import { WidgetDistribute } from './components/WidgetDistribute';
  import { DataSourceBindPanel } from '../dataSourceBindPanel';
  import { PageHeader } from './components/PagerHeader';
  import { useShare } from './hooks/useShare';
  import { useRole } from '/@/hooks/business/useRole';
  import { Authority } from '/@/components/Authority';
  import { useModal } from '/@/components/Modal';
  import { ModalParamsType } from '/#/utils';
  import { DataActionModeEnum } from '/@/enums/toolEnum';
  import { HistoryTrendModal } from './components/HistoryTrendModal';
  import { useSocket } from '../packages/hook/useSocket';
  import { watch } from 'vue';
  import { useRootSetting } from '/@/hooks/setting/useRootSetting';
  import { ThemeEnum } from '/@/enums/appEnum';

  const props = defineProps<{
    value?: Recordable;
  }>();

  const getProps = computed(() => props);

  const containerRefEl = ref<Nullable<HTMLDivElement>>(null);

  const containerRectRef = ref<DOMRect>({} as unknown as DOMRect);

  const { loading, draggable, resizable, dataSource, rawDataSource, setLayoutInfo, getDataSource } =
    useDataSource(getProps);

  const { resize, resized, moved, containerResized } = useDragGridLayout(dataSource, setLayoutInfo);

  const [register, { openModal }] = useModal();

  const [registerTrendModal, { openModal: openTrendModal }] = useModal();

  /**
   * @description 获取画板宽高
   */
  onMounted(() => {
    const rect = getBoundingClientRect(unref(containerRefEl)!);
    if (rect) {
      containerRectRef.value = rect as DOMRect;
    }
  });
  const { getIsSharePage } = useShare();
  const { isCustomerUser } = useRole();
  const handleOpenCreatePanel = () => {
    openModal(true, { mode: DataActionModeEnum.CREATE } as ModalParamsType);
  };

  const handleUpdateWidget = (data: WidgetDataType) => {
    openModal(true, { mode: DataActionModeEnum.UPDATE, record: data } as ModalParamsType);
  };

  const handleOpenTrend = (data: WidgetDataType) => {
    openTrendModal(true, { mode: DataActionModeEnum.READ, record: data } as ModalParamsType);
  };

  useSocket(dataSource);

  const { getDarkMode } = useRootSetting();
  watch(
    getIsSharePage,
    (value) => {
      if (value) {
        console.log(unref(getDarkMode));
        const root = document.querySelector('#app');
        (root as HTMLDivElement).style.backgroundColor =
          unref(getDarkMode) === ThemeEnum.LIGHT ? '#F5F5F5' : '#1b1b1b';
      }
    },
    { immediate: true }
  );
</script>

<template>
  <section
    ref="containerRefEl"
    class="palette w-full h-full flex-col bg-neutral-100 flex dark:bg-dark-700 dark:text-light-50"
  >
    <PageHeader :widget-number="dataSource.length">
      <Authority :value="VisualComponentPermission.CREATE">
        <Button
          v-if="!getIsSharePage && !isCustomerUser"
          type="primary"
          @click="handleOpenCreatePanel"
        >
          创建组件
        </Button>
      </Authority>
    </PageHeader>

    <Spin :spinning="loading">
      <GridLayout
        v-model:layout="dataSource"
        :col-num="DEFAULT_MAX_COL"
        :row-height="30"
        :margin="[DEFAULT_ITEM_MARIGN, DEFAULT_ITEM_MARIGN]"
        :is-draggable="draggable"
        :is-resizable="resizable"
        :vertical-compact="true"
        :use-css-transforms="true"
        style="width: 100%"
      >
        <GridItem
          v-for="item in dataSource"
          :key="item.i"
          :static="item.static"
          :x="item.x"
          :y="item.y"
          :w="item.w"
          :h="item.h"
          :i="item.i"
          :min-h="DEFAULT_MIN_HEIGHT"
          :min-w="DEFAULT_MIN_WIDTH"
          :style="{ display: 'flex', flexWrap: 'wrap' }"
          class="grid-item-layout"
          @resized="resized"
          @resize="resize"
          @moved="moved"
          @container-resized="containerResized"
          drag-ignore-from=".no-drag"
        >
          <WidgetWrapper>
            <template #header>
              <WidgetHeader
                :raw-data-source="rawDataSource"
                :source-info="item"
                @update="handleUpdateWidget"
                @open-trend="handleOpenTrend"
                @ok="getDataSource"
              />
            </template>
            <WidgetDistribute :source-info="item" />
          </WidgetWrapper>
        </GridItem>
      </GridLayout>
      <Empty
        v-if="!dataSource.length"
        class="fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
      />
    </Spin>

    <DataSourceBindPanel @register="register" :layout="dataSource" @ok="getDataSource" />

    <HistoryTrendModal @register="registerTrendModal" />
  </section>
</template>

<style lang="less" scoped></style>