github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/static_source/admin/src/views/Dashboard/editor/TabSettings.vue (about)

     1  <script setup lang="ts">
     2  import {computed, nextTick, PropType, reactive, ref, unref, watch} from 'vue'
     3  import {Form} from '@/components/Form'
     4  import {ElButton, ElCol, ElDivider, ElMessage, ElPopconfirm, ElRow} from 'element-plus'
     5  import {useI18n} from '@/hooks/web/useI18n'
     6  import {useForm} from '@/hooks/web/useForm'
     7  import {useValidator} from '@/hooks/web/useValidator'
     8  import {FormSchema} from '@/types/form'
     9  import {ApiArea, ApiDashboard} from "@/api/stub";
    10  import {copyToClipboard} from "@/utils/clipboard";
    11  import {JsonViewer} from "@/components/JsonViewer";
    12  import {Core, eventBus} from "@/views/Dashboard/core";
    13  import {useRouter} from "vue-router";
    14  import {Dialog} from '@/components/Dialog'
    15  
    16  const {register, elFormRef, methods} = useForm()
    17  const {required} = useValidator()
    18  const {t} = useI18n()
    19  const dialogSource = ref({})
    20  const dialogVisible = ref(false)
    21  const {setValues, setSchema} = methods
    22  const {currentRoute, addRoute, push} = useRouter()
    23  
    24  interface DashboardForm {
    25    name?: string;
    26    description?: string;
    27    enabled?: boolean;
    28    area?: ApiArea;
    29    areaId?: number;
    30  }
    31  
    32  const props = defineProps({
    33    core: {
    34      type: Object as PropType<Nullable<Core>>,
    35      default: () => null
    36    },
    37  })
    38  
    39  const currentCore = computed(() => props.core as Core)
    40  
    41  const rules = {
    42    name: [required()],
    43  }
    44  
    45  const schema = reactive<FormSchema[]>([
    46    {
    47      field: 'name',
    48      label: t('dashboard.name'),
    49      component: 'Input',
    50      colProps: {
    51        span: 24
    52      },
    53      componentProps: {
    54        placeholder: t('dashboard.name')
    55      }
    56    },
    57    {
    58      field: 'description',
    59      label: t('dashboard.description'),
    60      component: 'Input',
    61      colProps: {
    62        span: 24
    63      },
    64      componentProps: {
    65        placeholder: t('dashboard.description')
    66      }
    67    },
    68    // {
    69    //   field: 'enabled',
    70    //   label: t('dashboard.enabled'),
    71    //   component: 'Switch',
    72    //   value: false,
    73    //   colProps: {
    74    //     span: 24
    75    //   },
    76    // },
    77    {
    78      field: 'area',
    79      label: t('dashboard.area'),
    80      value: null,
    81      component: 'Area',
    82      colProps: {
    83        span: 24
    84      },
    85      componentProps: {
    86        placeholder: t('dashboard.area'),
    87      }
    88    },
    89  ])
    90  
    91  watch(
    92      () => props.core?.current,
    93      (val?: ApiDashboard) => {
    94        if (!val) return
    95        setValues({
    96          name: val.name,
    97          description: val.description,
    98          enabled: val.enabled,
    99          area: val.area,
   100          areaId: val.areaId,
   101        })
   102      },
   103      {
   104        deep: false,
   105        immediate: true
   106      }
   107  )
   108  
   109  const prepareForExport = async () => {
   110    return ""
   111  }
   112  
   113  const copy = async () => {
   114    const body = await prepareForExport()
   115    copyToClipboard(JSON.stringify(body, null, 2))
   116  }
   117  
   118  
   119  const exportDashbord = () => {
   120    dialogSource.value = currentCore.value.serialize()
   121    dialogVisible.value = true
   122  }
   123  
   124  const updateBoard = async () => {
   125    const formRef = unref(elFormRef)
   126    await formRef?.validate(async (isValid) => {
   127      if (isValid) {
   128        const {getFormData} = methods
   129        const formData = await getFormData<DashboardForm>()
   130        const board = currentCore.value.current;
   131        board.areaId = formData.area?.id
   132        board.area = formData.area
   133        board.name = formData.name
   134        board.description = formData.description
   135        board.enabled = formData.enabled
   136        nextTick()
   137        const res = await currentCore.value?.update()
   138            .catch(() => {
   139            })
   140            .finally(() => {
   141              // fetchDashboard()
   142            })
   143        ElMessage({
   144          title: t('Success'),
   145          message: t('message.updatedSuccessfully'),
   146          type: 'success',
   147          duration: 2000
   148        });
   149      }
   150    })
   151  
   152  }
   153  
   154  const fetchDashboard = () => {
   155    eventBus.emit('fetchDashboard')
   156  }
   157  
   158  const cancel = () => {
   159    push(`/dashboards`)
   160  }
   161  
   162  const removeBoard = async () => {
   163    if (!currentCore.value) return;
   164    await currentCore.value.removeBoard()
   165        .catch(() => {
   166        })
   167        .finally(() => {
   168        })
   169    cancel()
   170  }
   171  
   172  </script>
   173  
   174  <template>
   175  
   176    <ElRow class="mb-10px">
   177      <ElCol>
   178        <ElDivider content-position="left">{{ $t('dashboard.mainTab') }}</ElDivider>
   179      </ElCol>
   180    </ElRow>
   181  
   182    <Form
   183        :schema="schema"
   184        :rules="rules"
   185        label-position="top"
   186        @register="register"
   187        class="mb-10px"
   188    />
   189  
   190  
   191    <ElRow class="mb-10px">
   192      <ElCol>
   193        <ElDivider class="mb-10px" content-position="left">{{ $t('main.actions') }}</ElDivider>
   194      </ElCol>
   195    </ElRow>
   196  
   197  
   198    <div class="text-right">
   199  
   200      <ElButton type="primary" @click.prevent.stop='exportDashbord' plain>
   201        <Icon icon="uil:file-export" class="mr-5px"/>
   202        {{ $t('main.export') }}
   203      </ElButton>
   204  
   205  
   206      <ElButton type="primary" @click.prevent.stop="updateBoard" plain>
   207        {{ $t('main.update') }}
   208      </ElButton>
   209  
   210  
   211      <ElButton @click.prevent.stop="fetchDashboard" plain>{{
   212          $t('main.loadFromServer')
   213        }}
   214      </ElButton>
   215  
   216      <ElPopconfirm
   217          :confirm-button-text="$t('main.ok')"
   218          :cancel-button-text="$t('main.no')"
   219          width="250"
   220          style="margin-left: 10px;"
   221          :title="$t('main.are_you_sure_to_do_want_this?')"
   222          @confirm="removeBoard"
   223      >
   224        <template #reference>
   225          <ElButton type="danger" plain>
   226            <Icon icon="ep:delete" class="mr-5px"/>
   227            {{ t('main.remove') }}
   228          </ElButton>
   229        </template>
   230      </ElPopconfirm>
   231  
   232    </div>
   233  
   234    <!-- export dialog -->
   235    <Dialog v-model="dialogVisible" :title="t('main.dialogExportTitle')" :maxHeight="400" width="80%">
   236      <JsonViewer v-model="dialogSource"/>
   237      <template #footer>
   238        <ElButton @click="copy()">{{ t('setting.copy') }}</ElButton>
   239        <ElButton @click="dialogVisible = false">{{ t('main.closeDialog') }}</ElButton>
   240      </template>
   241    </Dialog>
   242    <!-- /export dialog -->
   243  
   244  </template>