/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the
NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses
this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance
with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless
required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS
IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific
language governing permissions and * limitations under the License. */

<template>
  <div class="topo-group">
    <div class="topo-group-wrapper">
      <div v-for="i in pagedData" :key="i.id">
        <GroupItem
          :servicesMap="servicesMap"
          :active="rocketTopoGroup.groupId === i.id"
          :key="i.id"
          @delete="handleDeleteGroup(i.id)"
          @select="handleSelectGroup"
          :data="i"
        />
      </div>
    </div>
    <RkPage
      v-show="rocketTopoGroup.groups.length > 10"
      :total="rocketTopoGroup.groups.length"
      @changePage="page"
      :currentPage="currentPage"
    />
    <CreateGroup />
  </div>
</template>
<script lang="ts">
  import topo, { State as topoState } from '@/store/modules/topology';
  import { Component, Vue, Watch } from 'vue-property-decorator';
  import { Action, Getter, Mutation, State } from 'vuex-class';
  import { State as TopoGroupState } from '@/store/modules/topology/group';
  import CreateGroup from './create-group.vue';
  import GroupItem from './group-item.vue';
  import Axios, { AxiosResponse } from 'axios';

  @Component({
    components: {
      CreateGroup,
      GroupItem,
    },
  })
  export default class TopoGroup extends Vue {
    @State('rocketTopo') private stateTopo!: topoState;
    @State('rocketTopoGroup') private rocketTopoGroup!: TopoGroupState;
    @Getter('durationTime') private durationTime: any;
    @Getter('rocketTopoGroup/services') private services!: Array<{ label: string; key: string }>;
    @Mutation('rocketTopoGroup/INIT_GROUPS') private INIT_GROUPS: any;
    @Mutation('rocketTopoGroup/DELETE_GROUP') private DELETE_GROUP: any;
    @Mutation('rocketTopoGroup/SELECT_GROUP') private SELECT_GROUP: any;
    @Mutation('SET_EVENTS') private SET_EVENTS: any;
    @Action('rocketTopo/GET_TOPO') private GET_TOPO: any;
    private servicesMap = [];
    private currentPage = 1;
    private get pagedData() {
      const start = 10 * this.currentPage;
      let end = 10;
      if (start < this.rocketTopoGroup.groups.length) {
        end = start;
      } else {
        end = this.rocketTopoGroup.groups.length;
      }
      return this.rocketTopoGroup.groups.slice(start - 10, end);
    }
    private page(pageNumber: number) {
      this.currentPage = pageNumber;
    }
    private handleDeleteGroup(id: string) {
      const r = confirm('Do you want to delete this group!');
      if (r === true) {
        this.DELETE_GROUP(id);
      }
    }
    private handleSelectGroup(id: string) {
      this.SELECT_GROUP(id);
      this.GET_TOPO({ duration: this.durationTime, serviceIds: this.services.map((i) => i.key) });
    }
    private fetchData() {
      return Axios.post('/graphql', {
        query: `
          query queryServices($duration: Duration!) {
            services: getAllServices(duration: $duration) {
              key: id
              label: name
            }
          }`,
        variables: {
          duration: this.durationTime,
        },
      }).then((res: AxiosResponse) => {
        this.servicesMap = res.data.data.services ? res.data.data.services : [];
      });
    }
    private initGroupTopo() {
      let serviceOld = localStorage.getItem('topology-group-history') || '';
      if (!this.rocketTopoGroup.groups.length) {
        return;
      }
      if (
        !this.rocketTopoGroup.groups.some(
          (i: { id: string; name: string; services: Array<{ label: string; key: string }> }) => i.id === serviceOld,
        )
      ) {
        serviceOld = this.rocketTopoGroup.groups[0].id;
        this.handleSelectGroup(serviceOld);
      } else {
        this.handleSelectGroup(serviceOld);
      }
    }
    private created() {
      this.INIT_GROUPS();
      this.fetchData().then(() => {
        this.initGroupTopo();
      });
    }
  }
</script>
<style lang="scss">
  .topo-group {
    position: absolute;
    bottom: 10px;
    left: 10px;
    .rk-page {
      color: #eee;
    }
  }
</style>
