From 46ef63fb9f3c2688118a9d1511293128cfdfe4c9 Mon Sep 17 00:00:00 2001
From: Zephyrrus <krisztian1997@gmail.com>
Date: Sun, 10 Jan 2021 02:04:35 +0200
Subject: feat: add dynamic settings page rendering based on the Joi object

---
 src/site/components/settings/JoiObject.vue | 141 +++++++++++++++++++++++++++++
 1 file changed, 141 insertions(+)
 create mode 100644 src/site/components/settings/JoiObject.vue

(limited to 'src/site/components/settings/JoiObject.vue')

diff --git a/src/site/components/settings/JoiObject.vue b/src/site/components/settings/JoiObject.vue
new file mode 100644
index 0000000..e842792
--- /dev/null
+++ b/src/site/components/settings/JoiObject.vue
@@ -0,0 +1,141 @@
+<template>
+	<div v-if="keys">
+		<div v-for="[key, field] in Object.entries(keys)" :key="key">
+			<b-field
+				:label="field.flags.label"
+				:message="field.flags.description"
+				class="field"
+				horizontal>
+				<b-input
+					v-if="getDisplayType(field) === 'string'"
+					v-model="settings.serviceName"
+					class="chibisafe-input"
+					expanded />
+				<b-input
+					v-else-if="getDisplayType(field) === 'number'"
+					v-model="settings.serviceName"
+					type="number"
+					class="chibisafe-input"
+					:min="getMin(field)"
+					:max="getMax(field)"
+					expanded />
+				<b-switch
+					v-else-if="getDisplayType(field) === 'boolean'"
+					v-model="settings.publicMode"
+					:rounded="false"
+					:true-value="true"
+					:false-value="false" />
+				<b-taginput
+					v-else-if="getDisplayType(field) === 'array' || getDisplayType(field) === 'tagInput'"
+					v-model="settings.arr"
+					ellipsis
+					icon="label"
+					:placeholder="field.flags.label"
+					aria-close-label="Delete this tag"
+					class="taginp" />
+				<div v-else-if="getDisplayType(field) === 'checkbox'">
+					<b-checkbox v-for="item in getAllowedItems(field)" :key="item"
+						v-model="settings.ech"
+						:native-value="item">
+						{{ item }}
+					</b-checkbox>
+				</div>
+			</b-field>
+			<!--
+				TODO: Add asterisk to required fields
+				TODO: Implement showing errors returned by backend/joi
+			-->
+		</div>
+	</div>
+</template>
+
+
+<script>
+export default {
+	name: 'JoiObject',
+	props: {
+		keys: {
+			type: Object,
+			required: true
+		},
+		values: {
+			type: Object,
+			required: true
+		},
+		errors: {
+			'type': Object,
+			'default': {}
+		}
+	},
+	data() {
+		return {
+			fields: null, // keys + values combined
+			settings: {
+				ech: []
+			}
+		};
+	},
+	mounted() {
+		// TODO: Implement merging fields with values from the db (no endpoint to fetch settings yet)
+	},
+	methods: {
+		getMin(field) {
+			if (field.type !== 'number') return;
+
+			for (const rule of field.rules) {
+				if (rule.name === 'greater') return rule.args.limit + 1;
+				if (rule.name === 'min') return rule.args.limit;
+			}
+		},
+		getMax(field) {
+			if (field.type !== 'number') return;
+
+			for (const rule of field.rules) {
+				if (rule.name === 'less') return rule.args.limit - 1;
+				if (rule.name === 'max') return rule.args.limit;
+			}
+		},
+		getDisplayType(field) {
+			if (!field.metas) return field.type;
+
+			const { displayType } = field.metas.find(e => e.displayType);
+
+			if (displayType) return displayType;
+
+			return field.type;
+		},
+		getAllowedItems(field) {
+			if (!field.items) return [];
+
+			return field.items.reduce((acc, item) => {
+				if (!item.allow) return acc;
+
+				return [...acc, ...item.allow];
+			}, []);
+		}
+	}
+};
+</script>
+<style lang="scss" scoped>
+	@import '~/assets/styles/_colors.scss';
+
+	.field {
+		margin-bottom: 1em;
+	}
+
+	.taginp {
+		::v-deep {
+			.taginput-container {
+				border-color: #585858;
+			}
+
+			.input::placeholder {
+				color: $textColor;
+			}
+
+			.taginput-container, .control, .input  {
+				background-color: transparent;
+			}
+		}
+	}
+</style>
-- 
cgit v1.2.3


From d69fcd856a47b04f964c658edfa2bed3e6f0abc1 Mon Sep 17 00:00:00 2001
From: Zephyrrus <krisztian1997@gmail.com>
Date: Mon, 11 Jan 2021 12:51:45 +0200
Subject: feat: add sections to settings object meta

---
 src/site/components/settings/JoiObject.vue | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'src/site/components/settings/JoiObject.vue')

diff --git a/src/site/components/settings/JoiObject.vue b/src/site/components/settings/JoiObject.vue
index e842792..c91fd36 100644
--- a/src/site/components/settings/JoiObject.vue
+++ b/src/site/components/settings/JoiObject.vue
@@ -25,6 +25,7 @@
 					:rounded="false"
 					:true-value="true"
 					:false-value="false" />
+				<!-- TODO: If array and has allowed items, limit input to those items only -->
 				<b-taginput
 					v-else-if="getDisplayType(field) === 'array' || getDisplayType(field) === 'tagInput'"
 					v-model="settings.arr"
@@ -76,7 +77,7 @@ export default {
 		};
 	},
 	mounted() {
-		// TODO: Implement merging fields with values from the db (no endpoint to fetch settings yet)
+
 	},
 	methods: {
 		getMin(field) {
-- 
cgit v1.2.3


From dc4f3a6557cc5f4ddf3d9a9bc8fad4f3bdc40c72 Mon Sep 17 00:00:00 2001
From: Zephyrrus <krisztian1997@gmail.com>
Date: Mon, 11 Jan 2021 18:57:19 +0200
Subject: fix: sections not rendering

---
 src/site/components/settings/JoiObject.vue | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'src/site/components/settings/JoiObject.vue')

diff --git a/src/site/components/settings/JoiObject.vue b/src/site/components/settings/JoiObject.vue
index c91fd36..af5b4eb 100644
--- a/src/site/components/settings/JoiObject.vue
+++ b/src/site/components/settings/JoiObject.vue
@@ -65,7 +65,7 @@ export default {
 		},
 		errors: {
 			'type': Object,
-			'default': {}
+			'default': () => ({})
 		}
 	},
 	data() {
@@ -99,9 +99,9 @@ export default {
 		getDisplayType(field) {
 			if (!field.metas) return field.type;
 
-			const { displayType } = field.metas.find(e => e.displayType);
+			const foundMeta = field.metas.find(e => e.displayType);
 
-			if (displayType) return displayType;
+			if (foundMeta) return foundMeta.displayType;
 
 			return field.type;
 		},
-- 
cgit v1.2.3

