Ui fixes and new features

This commit is contained in:
René Preuß
2023-02-18 23:03:43 +01:00
parent c0a53a7864
commit b40848aee2
11 changed files with 125 additions and 31 deletions

View File

@@ -1,15 +1,16 @@
<template> <template>
<a <button
href="#"
class="truncate text-black dark:text-white hover:bg-zinc-100 dark:bg-base-700 dark:hover:bg-base-600 dark:text-white rounded-lg px-4 py-2" class="truncate text-black dark:text-white hover:bg-zinc-100 dark:bg-base-700 dark:hover:bg-base-600 dark:text-white rounded-lg px-4 py-2"
@click="click"
> >
<slot /> <slot />
</a> </button>
</template> </template>
<script> <script>
export default { export default {
name: "BitinflowButton", name: "BitinflowButton",
emits: ['click'], emits: ['click'],
methods: { methods: {

View File

@@ -0,0 +1,33 @@
<template>
<nuxt-link
class="truncate text-black dark:text-white hover:bg-zinc-100 dark:bg-base-700 dark:hover:bg-base-600 dark:text-white rounded-lg px-4 py-2"
:to="to"
>
<slot />
</nuxt-link>
</template>
<script>
export default {
name: "BitinflowButton",
props: {
to: {
type: String,
required: true
}
},
emits: ['click'],
methods: {
click() {
this.$emit('click');
}
}
}
</script>
<style scoped>
</style>

View File

@@ -1,10 +1,13 @@
<template> <template>
<a class="hover:bg-primary-500 rounded-lg text-center text-xs py-4 flex flex-col space-y-2" href="#"> <nuxt-link
<i :class="['fal text-xl', icon]"></i> class="hover:bg-primary-500 rounded-lg text-center text-xs py-4 flex flex-col space-y-2"
href="#"
>
<i :class="['fal text-xl', icon]" />
<span> <span>
<slot /> <slot />
</span> </span>
</a> </nuxt-link>
</template> </template>
<script> <script>

View File

@@ -10,7 +10,7 @@
<header class="bg-white relative shadow sm:hidden z-10"> <header class="bg-white relative shadow sm:hidden z-10">
<div class="container flex justify-between items-center py-4"> <div class="container flex justify-between items-center py-4">
<img <img
src="/img/icon-light.svg" src="https://cdn.bitinflow.com/ui/images/brand/icon.svg"
class="h-4" class="h-4"
alt="bitinflow" alt="bitinflow"
> >
@@ -35,7 +35,7 @@
class="h-8 w-8 rounded-full" class="h-8 w-8 rounded-full"
alt="profile" alt="profile"
src="/img/avatar.jpg" src="/img/avatar.jpg"
/> >
</nuxt-link> </nuxt-link>
<button <button
@@ -72,7 +72,7 @@
<div class="flex-none bg-primary-500 h-16 sm:h-20 py-3 sm:py-6 text-white flex flex-initial justify-center"> <div class="flex-none bg-primary-500 h-16 sm:h-20 py-3 sm:py-6 text-white flex flex-initial justify-center">
<button @click="toggleDarkMode"> <button @click="toggleDarkMode">
<img <img
src="/img/icon-light.svg" src="https://cdn.bitinflow.com/ui/images/brand/icon-light.svg"
class="h-8 w-auto" class="h-8 w-auto"
alt="Logo" alt="Logo"
> >

View File

@@ -0,0 +1,25 @@
<template>
<bitinflow-button
class="flex items-center gap-2 w-full"
@click="$emit('click')"
>
<i :class="['fal', icon]" />
<slot />
</bitinflow-button>
</template>
<script>
import BitinflowButton from "./BitinflowButton.vue";
export default {
name: "BitinflowSecondLevelLink",
components: {BitinflowButton},
props: {
icon: {
type: String,
default: 'fa-arrow-up-right-from-square'
}
},
emits: ['click']
}
</script>

View File

@@ -1,19 +1,27 @@
<template> <template>
<bitinflow-button class="flex items-center gap-2"> <bitinflow-button-link
<i :class="['fal', icon]" /> <slot /> class="flex items-center gap-2"
</bitinflow-button> :to="to"
>
<i :class="['fal', icon]" />
<slot />
</bitinflow-button-link>
</template> </template>
<script> <script>
import BitinflowButton from "./BitinflowButton.vue"; import BitinflowButtonLink from "./BitinflowButtonLink.vue";
export default { export default {
name: "BitinflowSecondLevelLink", name: "BitinflowSecondLevelLink",
components: {BitinflowButton}, components: {BitinflowButtonLink},
props: { props: {
icon: { icon: {
type: String, type: String,
default: 'fa-arrow-up-right-from-square' default: 'fa-arrow-up-right-from-square'
},
to: {
type: String,
required: true
} }
} }
} }

View File

@@ -1,6 +1,8 @@
<!-- eslint-disable vue/require-explicit-emits -->
<template> <template>
<nav <nav
class="w-64 bg-white text-black shadow dark:bg-base-700 dark:text-white dark:border-base-900 dark:border-l flex flex-col overflow-y-auto h-screen absolute sm:relative transform -translate-x-full sm:translate-x-0 pt-10 pb-4 px-4 space-y-2"> class="w-64 bg-white text-black shadow dark:bg-base-700 dark:text-white dark:border-base-900 dark:border-l flex flex-col overflow-y-auto h-screen absolute sm:relative transform -translate-x-full sm:translate-x-0 pt-10 pb-4 px-4 space-y-2"
>
<span class="font-semibold px-4"> <span class="font-semibold px-4">
<slot name="title" /> <slot name="title" />
</span> </span>
@@ -8,24 +10,26 @@
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<slot /> <slot />
</div> </div>
<div> <div v-if="hasCreateListener">
<bitinflow-second-level-link <bitinflow-second-level-button
class="bg-zinc-100 hover:bg-zinc-200 dark:bg-base-500 dark:hover:bg-base-600" class="bg-zinc-100 hover:bg-zinc-200 dark:bg-base-500 dark:hover:bg-base-600"
icon="fa-plus" icon="fa-plus"
@click="$emit('create')"
> >
Create Resource Create Resource
</bitinflow-second-level-link> </bitinflow-second-level-button>
</div> </div>
</div> </div>
</nav> </nav>
</template> </template>
<script> <script>
import BitinflowSecondLevelLink from "./BitinflowSecondLevelLink.vue"; import BitinflowSecondLevelButton from "./BitinflowSecondLevelButton.vue";
export default { export default {
name: "BitinflowSecondLevelMenu", name: "BitinflowSecondLevelMenu",
components: {BitinflowSecondLevelLink}, components: {BitinflowSecondLevelButton},
props: { props: {
items: { items: {
type: Array, type: Array,
@@ -34,7 +38,13 @@ export default {
{name: 'Test', href: 'Test'} {name: 'Test', href: 'Test'}
] ]
} }
} },
computed: {
hasCreateListener() {
return this.$attrs && this.$attrs.onCreate;
}
},
} }
</script> </script>

View File

@@ -11,27 +11,29 @@
<nav class="bg-white dark:bg-base-700 py-4"> <nav class="bg-white dark:bg-base-700 py-4">
<div class="container mx-auto px-4 lg:px-16"> <div class="container mx-auto px-4 lg:px-16">
<div class="hidden xl:block space-x-4"> <div class="hidden xl:block space-x-4">
<bitinflow-button <bitinflow-button-link
v-for="item in thirdLevelLinks" v-for="item in thirdLevelLinks"
:key="item.name" :key="item.name"
:to="resolve(item.to)"
> >
<i <i
:class="['far', item.icon]" :class="['far', item.icon]"
class="icon" class="icon"
/> {{ link.name }} /> {{ item.name }}
</bitinflow-button> </bitinflow-button-link>
</div> </div>
<div class="flex flex-col xl:hidden"> <div class="flex flex-col xl:hidden">
<select <select
v-model="link" v-model="link"
class="bg-white" class="bg-white dark:bg-base-700 outline-none"
@change="onChange" @change="onChange"
> >
<option <option
v-for="item in thirdLevelLinks" v-for="item in thirdLevelLinks"
:key="item.name" :key="item.name"
:value="item.to" :value="resolve(item.to)"
:selected="link === item.to"
> >
{{ item.name }} {{ item.name }}
</option> </option>
@@ -45,23 +47,27 @@
<script> <script>
import {mapState} from "pinia"; import {mapState} from "pinia";
import {useMenuStore} from "../stores/menu"; import {useMenuStore} from "../stores/menu";
import BitinflowButton from "./BitinflowButton.vue"; import BitinflowButtonLink from "./BitinflowButtonLink.vue";
export default { export default {
name: "BitinflowThirdLevelMenu", name: "BitinflowThirdLevelMenu",
components: {BitinflowButton}, components: {BitinflowButtonLink},
data() { data() {
return { return {
link: '' link: this.$route.path
} }
}, },
computed: { computed: {
...mapState(useMenuStore, ['thirdLevelLinks']) ...mapState(useMenuStore, ['thirdLevelLinks', 'thirdLevelProps'])
}, },
methods: { methods: {
onChange(event) { onChange(event) {
this.link = event.target.value this.link = event.target.value
this.$router.push(event.target.value) this.$router.push(event.target.value)
},
resolve(to) {
// replace all :params with the actual values
return to.replace(/:([^/]+)/g, (_, param) => this.thirdLevelProps[param])
} }
} }
} }

View File

@@ -6,4 +6,7 @@ export const useMenu = (options: MenuOptions) => {
if (options.thirdLevelLinks) { if (options.thirdLevelLinks) {
menu.updateThirdLevelLinks(options.thirdLevelLinks) menu.updateThirdLevelLinks(options.thirdLevelLinks)
} }
if (options.thirdLevelProps) {
menu.updateThirdLevelProps(options.thirdLevelProps)
}
} }

View File

@@ -4,12 +4,16 @@ import {ThirdLevelLink} from "../../types";
export const useMenuStore = defineStore('menu', { export const useMenuStore = defineStore('menu', {
state: () => { state: () => {
return { return {
thirdLevelLinks: [] as Array<ThirdLevelLink> thirdLevelLinks: [] as Array<ThirdLevelLink>,
thirdLevelProps: [] as Object,
} }
}, },
actions: { actions: {
updateThirdLevelLinks(links: Array<ThirdLevelLink>) { updateThirdLevelLinks(links: Array<ThirdLevelLink>) {
this.thirdLevelLinks = links; this.thirdLevelLinks = links;
}, },
updateThirdLevelProps(props: Object) {
this.thirdLevelProps = props;
}
}, },
}) })

View File

@@ -1,5 +1,6 @@
export interface MenuOptions { export interface MenuOptions {
thirdLevelLinks: Array<ThirdLevelLink>; thirdLevelLinks: Array<ThirdLevelLink>;
thirdLevelProps: Object;
} }
export interface ThirdLevelLink { export interface ThirdLevelLink {