changeset 2408:02d30251d594

client: table component for unified style
author Markus Kottlaender <markus@intevation.de>
date Thu, 28 Feb 2019 11:25:50 +0100
parents 8fc546b03822
children d9758395e09d
files client/src/components/ui/UIBoxHeader.vue client/src/components/ui/UITableBody.vue client/src/components/ui/UITableHeader.vue client/src/components/ui/box/Header.vue client/src/main.js
diffstat 5 files changed, 218 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/components/ui/UIBoxHeader.vue	Thu Feb 28 11:25:50 2019 +0100
@@ -0,0 +1,63 @@
+<template>
+  <h6 class="box-header">
+    <span class="box-title">
+      <font-awesome-icon
+        :icon="icon"
+        class="box-icon"
+        v-if="icon"
+        fixed-width
+      />
+      {{ $gettext(title) }}
+    </span>
+    <span class="box-close" @click="closeCallback" v-if="closeCallback">
+      <font-awesome-icon icon="times" />
+    </span>
+  </h6>
+</template>
+
+<style lang="sass">
+.box-header
+  display: flex
+  justify-content: space-between
+  align-items: center
+  min-height: 35px
+  padding-left: .5rem
+  border-bottom: 1px solid #dee2e6
+  color: $color-info
+  margin-bottom: 0
+  padding: 0.25rem
+  font-weight: bold
+  .box-title
+    padding-left: 0.25rem
+    .box-icon
+      margin-right: 0.25rem
+  .box-close
+    color: #888
+    padding: 3px 7px
+    border-radius: 0.25rem
+    cursor: pointer
+    transition: background-color 0.3s, color 0.3s
+    &:hover
+      color: #666
+      background-color: #eee
+</style>
+
+<script>
+/* This is Free Software under GNU Affero General Public License v >= 3.0
+ * without warranty, see README.md and license for details.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ * License-Filename: LICENSES/AGPL-3.0.txt
+ *
+ * Copyright (C) 2018 by via donau
+ *   – Österreichische Wasserstraßen-Gesellschaft mbH
+ * Software engineering by Intevation GmbH
+ *
+ * Author(s):
+ * Markus Kottländer <markus.kottlaender@intevation.de>
+ */
+
+export default {
+  props: ["icon", "title", "closeCallback"]
+};
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/components/ui/UITableBody.vue	Thu Feb 28 11:25:50 2019 +0100
@@ -0,0 +1,49 @@
+<template>
+  <div
+    class="table-body text-left small"
+    :style="'overflow-y: auto; max-height: ' + maxHeight"
+    v-if="data.length"
+  >
+    <div
+      v-for="(item, index) in data"
+      :key="index"
+      :class="['border-top row mx-0', { active: active === item }]"
+    >
+      <slot :item="item" :index="index"></slot>
+    </div>
+  </div>
+  <div v-else class="small text-center py-3 border-top">
+    <translate>No results.</translate>
+  </div>
+</template>
+
+<script>
+/* This is Free Software under GNU Affero General Public License v >= 3.0
+ * without warranty, see README.md and license for details.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ * License-Filename: LICENSES/AGPL-3.0.txt
+ *
+ * Copyright (C) 2018 by via donau
+ *   – Österreichische Wasserstraßen-Gesellschaft mbH
+ * Software engineering by Intevation GmbH
+ *
+ * Author(s):
+ * Markus Kottländer <markus.kottlaender@intevation.de>
+ */
+
+export default {
+  props: {
+    data: {
+      type: Array
+    },
+    maxHeight: {
+      type: String,
+      default: "18rem"
+    },
+    active: {
+      type: [Object, Array]
+    }
+  }
+};
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/components/ui/UITableHeader.vue	Thu Feb 28 11:25:50 2019 +0100
@@ -0,0 +1,94 @@
+<template>
+  <div
+    :class="['table-header row no-gutters bg-light', { sortable: sortable }]"
+  >
+    <a
+      v-for="column in columns"
+      @click.prevent="sortBy(column.id)"
+      :key="column.id"
+      :class="[
+        'd-flex py-2 align-items-center justify-content-center small col ' +
+          column.class,
+        { active: sortColumn === column.id }
+      ]"
+    >
+      <span
+        :style="'opacity: ' + (sortColumn === column.id ? '1' : '0.3')"
+        v-if="sortable"
+      >
+        <font-awesome-icon
+          :icon="sortIcon(column.id)"
+          class="ml-1"
+          fixed-width
+        />
+      </span>
+      {{ $gettext(column.title) }}
+    </a>
+    <div v-if="extraColumnForButtons" class="col"></div>
+  </div>
+</template>
+
+<style lang="sass">
+.table-header
+  > a
+    border-right: solid 1px #e7e8e9
+    background-color: #f8f9fa
+    a
+      outline: none
+      &:hover
+        text-decoration: none
+        background-color: #f8f9fa
+  &.sortable
+    a
+      cursor: pointer
+      &:hover,
+      &.active
+        background: #e7e8e9
+</style>
+
+<script>
+/* This is Free Software under GNU Affero General Public License v >= 3.0
+ * without warranty, see README.md and license for details.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ * License-Filename: LICENSES/AGPL-3.0.txt
+ *
+ * Copyright (C) 2018 by via donau
+ *   – Österreichische Wasserstraßen-Gesellschaft mbH
+ * Software engineering by Intevation GmbH
+ *
+ * Author(s):
+ * Markus Kottländer <markus.kottlaender@intevation.de>
+ */
+export default {
+  props: {
+    columns: { type: Array },
+    sortable: { type: Boolean, default: true },
+    extraColumnForButtons: { type: Boolean, default: true }
+  },
+  data() {
+    return {
+      sortColumn: null,
+      sortDirection: "ASC"
+    };
+  },
+  methods: {
+    sortIcon(id) {
+      if (this.sortColumn === id) {
+        return "sort-" + (this.sortDirection === "ASC" ? "down" : "up");
+      }
+      return "sort";
+    },
+    sortBy(id) {
+      if (this.sortable) {
+        this.sortColumn = id;
+        this.sortDirection = this.sortDirection === "ASC" ? "DESC" : "ASC";
+        this.$emit("sortingChanged", {
+          sortColumn: this.sortColumn,
+          sortDirection: this.sortDirection
+        });
+      }
+    }
+  }
+};
+</script>
--- a/client/src/components/ui/box/Header.vue	Thu Feb 28 10:30:33 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-<template>
-  <h6 class="box-header">
-    <span class="box-title">
-      <font-awesome-icon
-        :icon="icon"
-        class="box-icon"
-        v-if="icon"
-        fixed-width
-      />
-      {{ $gettext(title) }}
-    </span>
-    <span class="box-close" @click="closeCallback" v-if="closeCallback">
-      <font-awesome-icon icon="times" />
-    </span>
-  </h6>
-</template>
-
-<style lang="sass">
-.box-header
-  display: flex
-  justify-content: space-between
-  align-items: center
-  min-height: 35px
-  padding-left: .5rem
-  border-bottom: 1px solid #dee2e6
-  color: $color-info
-  margin-bottom: 0
-  padding: 0.25rem
-  font-weight: bold
-  .box-title
-    padding-left: 0.25rem
-    .box-icon
-      margin-right: 0.25rem
-  .box-close
-    color: #888
-    padding: 3px 7px
-    border-radius: 0.25rem
-    cursor: pointer
-    transition: background-color 0.3s, color 0.3s
-    &:hover
-      color: #666
-      background-color: #eee
-</style>
-
-<script>
-/* This is Free Software under GNU Affero General Public License v >= 3.0
- * without warranty, see README.md and license for details.
- *
- * SPDX-License-Identifier: AGPL-3.0-or-later
- * License-Filename: LICENSES/AGPL-3.0.txt
- *
- * Copyright (C) 2018 by via donau
- *   – Österreichische Wasserstraßen-Gesellschaft mbH
- * Software engineering by Intevation GmbH
- *
- * Author(s):
- * Markus Kottländer <markus.kottlaender@intevation.de>
- */
-
-export default {
-  props: ["icon", "title", "closeCallback"]
-};
-</script>
--- a/client/src/main.js	Thu Feb 28 10:30:33 2019 +0100
+++ b/client/src/main.js	Thu Feb 28 11:25:50 2019 +0100
@@ -29,7 +29,9 @@
 import store from "./store";
 import translations from "./locale/translations.json";
 import { supportedLanguages, defaultLanguage } from "./locale/languages.js";
-import Header from "@/components/ui/box/Header";
+import UIBoxHeader from "@/components/ui/UIBoxHeader";
+import UITableHeader from "@/components/ui/UITableHeader";
+import UITableBody from "@/components/ui/UITableBody";
 
 // styles
 import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
@@ -74,8 +76,11 @@
   faRuler,
   faSearch,
   faShip,
+  faSort,
   faSortAmountDown,
   faSortAmountUp,
+  faSortDown,
+  faSortUp,
   faSpinner,
   faStar,
   faTasks,
@@ -126,6 +131,9 @@
   faRuler,
   faSearch,
   faShip,
+  faSort,
+  faSortDown,
+  faSortUp,
   faSortAmountDown,
   faSortAmountUp,
   faSpinner,
@@ -154,7 +162,9 @@
 
 // register global components
 Vue.component("font-awesome-icon", FontAwesomeIcon);
-Vue.component("UIBoxHeader", Header);
+Vue.component("UIBoxHeader", UIBoxHeader);
+Vue.component("UITableHeader", UITableHeader);
+Vue.component("UITableBody", UITableBody);
 
 // global vue config
 Vue.config.productionTip = false;