Browse Source

feat: added styling to more things, added DataTable for accounts/schemas

Kristian Vos 5 years ago
parent
commit
8ce5b7caf5

+ 23 - 2
frontend/vue/App.vue

@@ -22,11 +22,32 @@ export default {
 
 <style lang="scss">
 body {
-	padding: 50px;
-	margin: 0;
 	font-family: Roboto, 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 	background-color: lightgray;
 }
+
+* {
+	margin: 0;
+	padding: 0;
+}
+
+main {
+	padding: 25px 50px;
+}
+
+.button {
+	padding: 8px 12px;
+	background-color: rgb(45, 150, 185);
+	color: white;
+	text-decoration: none;
+	display: inline-block;
+	box-shadow: none;
+	border: none;
+}
+
+input {
+	padding: 8px 12px;
+}
 </style>
 
 <style lang="scss" scoped>

+ 0 - 37
frontend/vue/components/AccountsList.vue

@@ -1,37 +0,0 @@
-<template>
-	<div class="accounts-list">
-		<div class="account" v-for="(account, accountIndex) in accounts">
-			{{ account.fields.name[0].name }}
-			<router-link
-				:to="`/accounts/edit/${account._id}`"
-			>
-				Edit account
-			</router-link>
-		</div>
-	</div>
-</template>
-
-<script>
-export default {
-	data: function() {
-		return {
-			
-		};
-	},
-	methods: {
-		
-	},
-	props: {
-		accounts: Array
-	},
-	mounted() {
-	},
-	methods: {
-		
-	}
-};
-</script>
-
-<style lang="scss" scoped>
-
-</style>

+ 88 - 0
frontend/vue/components/DataTable.vue

@@ -0,0 +1,88 @@
+<template>
+	<table>
+		<thead>
+			<tr>
+				<th v-for="field in fields">{{ field.displayName }}</th>
+			</tr>
+		</thead>
+		<tbody>
+			<tr v-for="data in computedData">
+				<td v-for="field in fields">
+					<span v-if="isFieldSlot(field.name)">
+						<slot :name="field.name" :data="data"></slot>
+					</span>
+					<span v-else>
+						{{ data[field.name] }}
+					</span>
+				</td>
+			</tr>
+		</tbody>
+	</table>
+</template>
+
+<script>
+export default {
+	components: {},
+	data: () => {
+		return {
+			
+		}
+	},
+	computed: {
+		computedData: function() {
+			let data = this.data;
+			this.sortOrder.reverse().forEach(orderItem => {
+				data = data.sort((a, b) => {
+					if (orderItem.order === "desc") return a[orderItem.field] < b[orderItem.field];
+					else return a[orderItem.field] > b[orderItem.field];
+				});
+			});
+			return data;
+		}
+	},
+	props: {
+		data: Array,
+		fields: Array,
+		sortOrder: Array
+	},
+	methods: {
+		isFieldSlot(name) {
+			return !!this.$scopedSlots[name];
+		}
+	},
+	mounted() {
+		
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+table {
+	background-color: white;
+}
+
+th, td {
+	padding: 8px;
+}
+
+th {
+	background-color: #eee;
+
+	&:hover {
+		background-color: #ddd;
+	}
+}
+
+td {
+	background-color: white;
+
+	&:hover {
+		background-color: #eee;
+	}
+}
+
+table, th, td {
+	border: 1px solid black;
+	border-collapse: collapse;
+}
+</style>

+ 35 - 3
frontend/vue/components/Navbar.vue

@@ -1,8 +1,20 @@
 <template>
 	<navbar>
-		<router-link to="/">Homepage</router-link>
-		<router-link to="/accounts">Accounts</router-link>
-		<router-link to="/schemas">Schemas</router-link>
+		<router-link to="/" v-slot="{ href, navigate, isExactActive }">
+			<a :class="{ 'active': isExactActive }" :href="href" @click="navigate">
+				Homepage
+			</a>
+		</router-link>
+		<router-link to="/accounts" v-slot="{ href, navigate, isExactActive }">
+			<a :class="{ 'active': isExactActive }" :href="href" @click="navigate">
+				Accounts
+			</a>
+		</router-link>
+		<router-link to="/schemas" v-slot="{ href, navigate, isExactActive }">
+			<a :class="{ 'active': isExactActive }" :href="href" @click="navigate">
+				Schemas
+			</a>
+		</router-link>
 	</navbar>
 </template>
 
@@ -24,5 +36,25 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+navbar {
+	display: flex;
+	width: 100%;
+	height: 60px;
+	background-color: green;
+	flex-direction: row;
 
+	a {
+		text-align: center;
+		padding: 10px;
+		vertical-align: middle;
+		line-height: 40px;
+		text-decoration: none;
+		color: white;
+		font-size: 20px;
+
+		&.active {
+			background-color: darkgreen;
+		}
+	}
+}
 </style>

+ 60 - 6
frontend/vue/pages/Accounts.vue

@@ -1,25 +1,79 @@
 <template>
 	<main>
 		<h1>Accounts</h1>
-		<router-link to="/accounts/add">
+		<hr/>
+		<br/>
+		<router-link
+			to="/accounts/add"
+			class="button"
+		>
 			Add account
 		</router-link>
-		<accounts-list
-			:accounts="accounts"
-		/>
+		<br/>
+		<br/>
+		<data-table ref="datatable"
+			:fields="fields"
+			:sort-order="sortOrder"
+			:data="localData"
+		>
+			<div slot="actions-slot" slot-scope="props">
+				<router-link
+					:to="`/accounts/edit/${props.data.accountId}`"
+					class="button"
+				>
+					Edit account
+				</router-link>
+			</div>
+		</data-table>
 	</main>
 </template>
 
 <script>
 import io from "../../io.js";
 
-import AccountsList from '../components/AccountsList.vue';
+import DataTable from '../components/DataTable.vue';
 
 export default {
-	components: { AccountsList },
+	components: { DataTable },
 	data: () => {
 		return {
 			accounts: [],
+			fields: [
+				{
+					name: "name",
+					displayName: "Name"
+				},
+				{
+					name: "domain",
+					displayName: "Domain(s)"
+				},
+				{
+					name: "email",
+					displayName: "Email(s)"
+				},
+				{
+					name: "actions-slot",
+					displayName: "Actions"
+				}
+			],
+			sortOrder: [
+				{
+					field: "name",
+					order: "asc"
+				}
+			]
+		}
+	},
+	computed: {
+		localData: function() {
+			return this.accounts.map(account => {
+				return {
+					name: account.fields.name[0].name,
+					domain: account.fields.domain.map(domain => domain.domain).join(", "),
+					email: account.fields.email.map(email => email.email).join(", "),
+					accountId: account._id
+				};
+			});
 		}
 	},
 	methods: {

+ 6 - 1
frontend/vue/pages/EditAccount.vue

@@ -1,5 +1,10 @@
 <template>
-	<account-form v-if="account.version" :onSubmit="onSubmit" :initialAccount="account"/>
+	<main>
+		<h1>Edit account</h1>
+		<hr/>
+		<br/>
+		<account-form v-if="account.version" :onSubmit="onSubmit" :initialAccount="account"/>
+	</main>
 </template>
 
 <script>

+ 6 - 4
frontend/vue/pages/Homepage.vue

@@ -1,14 +1,16 @@
 <template>
-	<div>
-		
-	</div>
+	<main>
+		<h1>Homepage</h1>
+	</main>
 </template>
 
 <script>
+import DataTable from '../components/DataTable.vue'
+
 import io from "../../io.js";
 
 export default {
-	components: {},
+	components: { DataTable },
 	data: () => {
 		return {
 			

+ 55 - 5
frontend/vue/pages/Schemas.vue

@@ -1,21 +1,71 @@
 <template>
 	<main>
+		<h1>Schemas</h1>
+		<hr/>
+		<br/>
 		<input v-model="importAccountSchemaName"/>
-		<button @click="importAccountSchema()">Import account schema</button>
-
-		<router-link v-for="schema in schemas" :to="`/schemas/${schema._id}`" class="schema-item">{{ schema.name }} v{{ schema.version }}</router-link>
+		<button @click="importAccountSchema()" class="button">Import account schema</button>
+		<br/>
+		<br/>
+		<data-table ref="datatable"
+			:fields="fields"
+			:sort-order="sortOrder"
+			:data="localData"
+		>
+			<div slot="actions-slot" slot-scope="props">
+				<router-link
+					:to="`/schemas/${props.data.schemaId}`"
+					class="button"
+				>
+					View schema
+				</router-link>
+			</div>
+		</data-table>
 	</main>
 </template>
 
 <script>
 import io from "../../io.js";
 
+import DataTable from '../components/DataTable.vue';
+
 export default {
-	components: {},
+	components: { DataTable },
 	data: () => {
 		return {
 			importAccountSchemaName: "",
-			schemas: []
+			schemas: [],
+			fields: [
+				{
+					name: "name",
+					displayName: "Name"
+				},
+				{
+					name: "version",
+					displayName: "Version"
+				},
+				{
+					name: "actions-slot",
+					displayName: "Actions"
+				}
+			],
+			sortOrder: [
+				{
+					field: "version",
+					order: "desc"
+				}
+			]
+		}
+	},
+	computed: {
+		localData: function() {
+			return this.schemas.map(schema => {
+				return {
+					name: schema.name,
+					version: schema.version,
+					schemaId: schema._id
+				};
+			});
 		}
 	},
 	methods: {

+ 3 - 0
frontend/vue/pages/ViewSchema.vue

@@ -1,5 +1,8 @@
 <template>
 	<main v-if="schema">
+		<h1>View schema</h1>
+		<hr/>
+		<br/>
 		<p><b>Name</b>: {{ schema.name }}</p>
 		<p><b>Description</b>: {{ schema.description }}</p>
 		<p><b>Version</b>: v{{ schema.version }}</p>