Skip to content
Snippets Groups Projects
FeatureListTable.vue 13.9 KiB
Newer Older

<template>
  <div data-tab="list" class="dataTables_wrapper no-footer">
    <table id="table-features" class="ui compact table">
      <thead>
        <tr>
          <th class="center"></th>

          <th class="center">
            Statut
            <i
              :class="{
                down: isSortedAsc('statut'),
                up: isSortedDesc('statut'),
              }"
              class="icon sort"
              @click="changeSort('statut')"
            />
          </th>
          <th class="center">
            Type
            <i
              :class="{
                down: isSortedAsc('type'),
                up: isSortedDesc('type'),
              }"
              class="icon sort"
              @click="changeSort('type')"
            />
          </th>
          <th class="center">
            Nom
            <i
              :class="{
                down: isSortedAsc('nom'),
                up: isSortedDesc('nom'),
              }"
              class="icon sort"
              @click="changeSort('nom')"
            />
          </th>
          <th class="center">
            Dernière modification
            <i
              :class="{
                down: isSortedAsc('updated_on'),
                up: isSortedDesc('updated_on'),
              }"
              class="icon sort"
              @click="changeSort('updated_on')"
            />
          </th>
          <th class="center" v-if="user">
            Auteur
            <i
              :class="{
                down: isSortedAsc('display_creator'),
                up: isSortedDesc('display_creator'),
              }"
              class="icon sort"
              @click="changeSort('display_creator')"
            />
          </th>
          <th class="center" v-if="user">
            Dernier éditeur
            <i
              :class="{
                down: isSortedAsc('display_last_editor'),
                up: isSortedDesc('display_last_editor'),
              }"
              class="icon sort"
              @click="changeSort('display_last_editor')"
            />
          </th>
        </tr>
      </thead>
      <tbody>
Timothee P's avatar
Timothee P committed
        <tr v-for="(feature, index) in sortedFeatures" :key="index">
          <td class="center">
            <div
              class="ui checkbox"
              :class="
Timothee P's avatar
Timothee P committed
                feature.properties.creator.username !== user.username &&
                !user.is_superuser &&
                !isUserProjectAdministrator
                  ? 'disabled'
                  : ''
              <input
                type="checkbox"
                :id="feature.id"
                :value="feature.id"
                v-model="checked"
Timothee P's avatar
Timothee P committed
                :disabled="
                  feature.properties.creator.username !== user.username &&
                  !user.is_superuser &&
                  !isUserProjectAdministrator
                "
              />
              <label></label>
            </div>
          </td>

          <td class="center">
            <div
              v-if="feature.properties.status.value === 'archived'"
              data-tooltip="Archivé"
            >
              <i class="grey archive icon"></i>
            </div>
            <div
              v-else-if="feature.properties.status.value === 'pending'"
              data-tooltip="En attente de publication"
            >
              <i class="teal hourglass outline icon"></i>
            </div>
            <div
              v-else-if="feature.properties.status.value === 'published'"
              data-tooltip="Publié"
            >
              <i class="olive check icon"></i>
            </div>
            <div
              v-else-if="feature.properties.status.value === 'draft'"
              data-tooltip="Brouillon"
            >
              <i class="orange pencil alternate icon"></i>
            </div>
          </td>
          <td class="center">
            <router-link
              :to="{
                name: 'details-type-signalement',
                params: {
                  feature_type_slug: feature.properties.feature_type.slug,
                },
              }"
            >
              {{ feature.properties.feature_type.title }}
            </router-link>
          </td>
          <td class="center">
            <router-link
              :to="{
                name: 'details-signalement',
                params: {
                  slug_type_signal: feature.properties.feature_type.slug,
                  slug_signal: feature.properties.slug || feature.id,
                },
              }"
              >{{ getFeatureDisplayName(feature) }}</router-link
            >
          </td>
          <td class="center">
            <!-- |date:'Ymd' -->
            {{ feature.properties.updated_on }}
          </td>
          <td class="center" v-if="user">
            {{ getUserName(feature) }}
          </td>
          <td class="center" v-if="user">
            {{ feature.properties.display_last_editor }}
          </td>
        </tr>
Timothee P's avatar
Timothee P committed
        <tr v-if="featuresCount === 0" class="odd">
          <td colspan="5" class="dataTables_empty" valign="top">
            Aucune donnée disponible
          </td>
        </tr>
      </tbody>
    </table>
Timothee P's avatar
Timothee P committed
    <!-- v-if="nbPages.length > 1" -->
<!--     <div
      id="table-features_info"
      role="status"
      aria-live="polite"
    >
      Affichage de l'élément {{ pagination.start + 1 }} à
      {{ displayedPageEnd }}
Timothee P's avatar
Timothee P committed
      sur {{ featuresCount }} éléments
    </div>
    <div
      id="table-features_paginate"
      class="dataTables_paginate paging_simple_numbers"
    >
      <a
        @click="toPreviousPage"
        id="table-features_previous"
        :class="[
          'paginate_button previous',
          { disabled: pagination.currentPage === 1 },
        ]"
        aria-controls="table-features"
        data-dt-idx="0"
        tabindex="0"
        >Précédent</a
      >
      <span>
        <a
Timothee P's avatar
Timothee P committed
          v-for="pageNumber in nbPages"
          :key="'page' + pageNumber"
          :class="[
            'paginate_button',
Timothee P's avatar
Timothee P committed
            { current: pageNumber === pagination.currentPage },
          ]"
          aria-controls="table-features"
          data-dt-idx="1"
          tabindex="0"
Timothee P's avatar
Timothee P committed
          >{{ pageNumber }}</a
        id="table-features_next"
        :class="[
          'paginate_button next',
          { disabled: pagination.currentPage === nbPages.length },
        ]"
        aria-controls="table-features"
        data-dt-idx="7"
        tabindex="0"
        @click="toNextPage"
        >Suivant</a
      >
Timothee P's avatar
Timothee P committed
    </div> -->
  </div>
</template>

<script>
Timothee P's avatar
Timothee P committed
import { mapState, mapGetters } from "vuex";
export default {
  name: "FeatureListTable",

Timothee P's avatar
Timothee P committed
  props: ["geojsonFeatures", "checkedFeatures", "featuresCount"],

  data() {
    return {
Timothee P's avatar
Timothee P committed
/*       pagination: {
        currentPage: 1,
        pagesize: 15,
        start: 0,
Timothee P's avatar
Timothee P committed
        end: 15,
Timothee P's avatar
Timothee P committed
      }, */
      sort: {
        column: "",
        ascending: true,
      },
    };
  },

  computed: {
Timothee P's avatar
Timothee P committed
    ...mapState(["user"]),
    ...mapGetters(["project", "permissions"]),

    isUserProjectAdministrator() {
      return this.permissions.is_project_administrator;
    },

Timothee P's avatar
Timothee P committed
    sortedFeatures() {
      let sortedFeatures = [...this.geojsonFeatures];
      // Ajout du tri
Timothee P's avatar
Timothee P committed
        sortedFeatures = sortedFeatures.sort((a, b) => {
          let aProp = this.getFeatureDisplayName(a);
          let bProp = this.getFeatureDisplayName(b);
          if (this.sort.column === "statut") {
            aProp = a.properties.status.value;
            bProp = b.properties.status.value;
          } else if (this.sort.column === "type") {
            aProp = a.properties.feature_type.title;
            bProp = b.properties.feature_type.title;
          } else if (this.sort.column === "updated_on") {
            aProp = a.properties.updated_on;
            bProp = b.properties.updated_on;
          } else if (this.sort.column === "display_creator") {
            aProp = a.properties.display_creator;
            bProp = b.properties.display_creator;
          }
          //ascending
          if (this.sort.ascending) {
            if (aProp < bProp) {
              return -1;
            }
            if (aProp > bProp) {
              return 1;
            }
            return 0;
          } else {
            //descending
            if (aProp < bProp) {
              return 1;
            }
            if (aProp > bProp) {
              return -1;
            }
            return 0;
          }
        });
      }
Timothee P's avatar
Timothee P committed
      return sortedFeatures;
Timothee P's avatar
Timothee P committed
/*     nbPages() {
      let N = Math.ceil(this.featuresCount / this.pagination.pagesize);
Timothee P's avatar
Timothee P committed
      const arr = [...Array(N).keys()].map(function (x) {
        ++x;
        return x;
      });
      return arr;
Timothee P's avatar
Timothee P committed
    }, */
    checked: {
      get() {
        return this.checkedFeatures;
      },
      set(newChecked) {
        this.$store.commit("feature/UPDATE_CHECKED_FEATURES", newChecked);
      },
    },
    displayedPageEnd() {
Timothee P's avatar
Timothee P committed
      return this.featuresCount <= this.pagination.end
        ? this.featuresCount
Timothee P's avatar
Timothee P committed
        : this.pagination.end;
Timothee P's avatar
Timothee P committed
    }, */
    getUserName(feature) {
      if (!feature.properties.creator) {
        return " ---- ";
      }
      return feature.properties.creator.username || " ---- ";
    getFeatureDisplayName(feature) {
      return feature.properties.title || feature.id;
    },

    isSortedAsc(column) {
      return this.sort.column === column && this.sort.ascending;
    },
    isSortedDesc(column) {
      return this.sort.column === column && !this.sort.ascending;
    },

    changeSort(column) {
      if (this.sort.column === column) {
        //changer order
        this.sort.ascending = !this.sort.ascending;
      } else {
        this.sort.column = column;
        this.sort.ascending = true;
      }
    },


  },
};
</script>

<style scoped>
/* datatables */
Timothee P's avatar
Timothee P committed
/* .dataTables_wrapper {
  position: relative;
  clear: both;
}
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter,
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_processing,
.dataTables_wrapper .dataTables_paginate {
  color: #333;
}
.dataTables_wrapper .dataTables_info {
  clear: both;
  float: left;
  padding-top: 0.755em;
}
.dataTables_wrapper .dataTables_paginate {
  float: right;
  text-align: right;
  padding-top: 0.25em;
}
.dataTables_wrapper .dataTables_paginate .paginate_button.current,
.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
  color: #333 !important;
  border: 1px solid #979797;
  background-color: white;
  background: -webkit-gradient(
    linear,
    left top,
    left bottom,
    color-stop(0%, #fff),
    color-stop(100%, #dcdcdc)
  );
  background: -webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%);
  background: -moz-linear-gradient(top, #fff 0%, #dcdcdc 100%);
  background: -ms-linear-gradient(top, #fff 0%, #dcdcdc 100%);
  background: -o-linear-gradient(top, #fff 0%, #dcdcdc 100%);
  background: linear-gradient(to bottom, #fff 0%, #dcdcdc 100%);
}
.dataTables_wrapper .dataTables_paginate .paginate_button {
  box-sizing: border-box;
  display: inline-block;
  min-width: 1.5em;
  padding: 0.5em 1em;
  margin-left: 2px;
  text-align: center;
  text-decoration: none !important;
  cursor: pointer;
  color: #333 !important;
  border: 1px solid transparent;
  border-radius: 2px;
}
.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
  color: white !important;
  border: 1px solid #111;
  background-color: #585858;
  background: -webkit-gradient(
    linear,
    left top,
    left bottom,
    color-stop(0%, #585858),
    color-stop(100%, #111)
  );
  background: -webkit-linear-gradient(top, #585858 0%, #111 100%);
  background: -moz-linear-gradient(top, #585858 0%, #111 100%);
  background: -ms-linear-gradient(top, #585858 0%, #111 100%);
  background: -o-linear-gradient(top, #585858 0%, #111 100%);
  background: linear-gradient(to bottom, #585858 0%, #111 100%);
}
.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,
.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,
.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {
  cursor: default;
  color: #666 !important;
  border: 1px solid transparent;
  background: transparent;
  box-shadow: none;
Timothee P's avatar
Timothee P committed
} */
i.icon.sort:not(.down):not(.up) {
  color: rgb(220, 220, 220);
}

/* 
Max width before this PARTICULAR table gets nasty
This query will take effect for any screen smaller than 760px
and also iPads specifically.
*/
@media only screen and (max-width: 760px),
  (min-device-width: 768px) and (max-device-width: 1024px) {
  /* Force table to not be like tables anymore */
  table,
  thead,
  tbody,
  th,
  td,
  tr {
    display: block;
  }

  /* Hide table headers (but not display: none;, for accessibility) */
  thead tr {
    position: absolute;
    top: -9999px;
    left: -9999px;
  }

  tr {
    border: 1px solid #ccc;
  }

  td {
    /* Behave  like a "row" */
    border: none;
    border-bottom: 1px solid #eee;
    position: relative;
    padding-left: 50%;
  }

  td:before {
    /* Now like a table header */
    position: absolute;
    /* Top/left values mimic padding */
    /* top: 6px; */
    left: 6px;
    /* width: 45%; */
    padding-right: 10px;
    white-space: nowrap;
  }

  /*
	Label the data
	*/
  td:nth-of-type(1):before {
    content: "";
  }
  td:nth-of-type(2):before {
    content: "Statut";
  }
  td:nth-of-type(3):before {
    content: "Type";
  }
  td:nth-of-type(4):before {
    content: "Nom";
  }
  td:nth-of-type(5):before {
    content: "Dernière modification";
  }
  td:nth-of-type(6):before {
    content: "Auteur";
  }

  .center {
    text-align: right !important;
  }

  #table-features {
    margin-left: 1em;
    width: calc(100% - 1em);
  }

  .ui.checkbox {
    position: absolute;
    left: -1.75em;
    top: 5em;
  }
}
</style>