fix: remove external dependency for icones (#805)

* change all icons to use iconify

* fix minor UI elements

* fix layout of table
This commit is contained in:
Hayden 2024-02-29 19:20:18 -06:00 committed by GitHub
parent cf166ac641
commit f91b33db38
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
40 changed files with 303 additions and 183 deletions

View file

@ -111,8 +111,6 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
@ -122,8 +120,6 @@ github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJm
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/olahol/melody v1.1.4 h1:RQHfKZkQmDxI0+SLZRNBCn4LiXdqxLKRGSkT8Dyoe/E= github.com/olahol/melody v1.1.4 h1:RQHfKZkQmDxI0+SLZRNBCn4LiXdqxLKRGSkT8Dyoe/E=
github.com/olahol/melody v1.1.4/go.mod h1:GgkTl6Y7yWj/HtfD48Q5vLKPVoZOH+Qqgfa7CvJgJM4= github.com/olahol/melody v1.1.4/go.mod h1:GgkTl6Y7yWj/HtfD48Q5vLKPVoZOH+Qqgfa7CvJgJM4=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU=
github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts=
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
@ -141,10 +137,6 @@ github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@ -235,8 +227,6 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
modernc.org/sqlite v1.29.1 h1:19GY2qvWB4VPw0HppFlZCPAbmxFU41r+qjKZQdQ1ryA=
modernc.org/sqlite v1.29.1/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0=
modernc.org/sqlite v1.29.2 h1:xgBSyA3gemwgP31PWFfFjtBorQNYpeypGdoSDjXhrgI= modernc.org/sqlite v1.29.2 h1:xgBSyA3gemwgP31PWFfFjtBorQNYpeypGdoSDjXhrgI=
modernc.org/sqlite v1.29.2/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0= modernc.org/sqlite v1.29.2/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0=
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=

View file

@ -1,4 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import MdiPlus from "~icons/mdi/mdi-plus";
const ctx = useAuthContext(); const ctx = useAuthContext();
const api = useUserApi(); const api = useUserApi();
@ -103,7 +105,7 @@
<div class="dropdown"> <div class="dropdown">
<label tabindex="0" class="btn btn-primary btn-sm"> <label tabindex="0" class="btn btn-primary btn-sm">
<span> <span>
<Icon name="mdi-plus" class="mr-1 -ml-1" /> <MdiPlus class="mr-1 -ml-1" />
</span> </span>
Create Create
</label> </label>

View file

@ -32,7 +32,7 @@
<input ref="importRef" type="file" class="hidden" accept=".csv,.tsv" @change="setFile" /> <input ref="importRef" type="file" class="hidden" accept=".csv,.tsv" @change="setFile" />
<BaseButton type="button" @click="uploadCsv"> <BaseButton type="button" @click="uploadCsv">
<Icon class="h-5 w-5 mr-2" name="mdi-upload" /> <MdiUpload class="h-5 w-5 mr-2" />
Upload Upload
</BaseButton> </BaseButton>
<p class="text-center pt-4 -mb-5"> <p class="text-center pt-4 -mb-5">
@ -48,6 +48,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import MdiUpload from "~icons/mdi/upload";
type Props = { type Props = {
modelValue: boolean; modelValue: boolean;
}; };

View file

@ -14,14 +14,14 @@
> >
<div class="flex gap-1"> <div class="flex gap-1">
<template v-if="notify.type == 'success'"> <template v-if="notify.type == 'success'">
<Icon name="heroicons-check" class="h-5 w-5" /> <MdiCheckboxMarkedCircle class="h-5 w-5" />
</template> </template>
<template v-if="notify.type == 'info'"> <template v-if="notify.type == 'info'">
<Icon name="heroicons-information-circle" class="h-5 w-5" /> <MdiInformationSlabCircle class="h-5 w-5" />
</template> </template>
<template v-if="notify.type == 'error'"> <template v-if="notify.type == 'error'">
<Icon name="heroicons-bell-alert" class="h-5 w-5" /> <MdiAlert class="h-5 w-5" />
</template> </template>
{{ notify.message }} {{ notify.message }}
</div> </div>
@ -31,6 +31,10 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import MdiCheckboxMarkedCircle from "~icons/mdi/checkbox-marked-circle";
import MdiInformationSlabCircle from "~icons/mdi/information-slab-circle";
import MdiAlert from "~icons/mdi/alert";
import { useNotifications } from "@/composables/use-notifier"; import { useNotifications } from "@/composables/use-notifier";
const { notifications, dropNotification } = useNotifications(); const { notifications, dropNotification } = useNotifications();

View file

@ -1,14 +0,0 @@
<template>
<div class="divider">
<div class="btn-group min-w-[180px] flex-nowrap">
<button name="options" class="btn btn-sm btn-primary" @click="$emit('edit')">
<Icon name="heroicons-pencil" class="h-5 w-5 mr-1" aria-hidden="true" />
<span> Edit </span>
</button>
<button name="options" class="btn btn-sm btn-primary" @click="$emit('delete')">
<Icon name="heroicons-trash" class="h-5 w-5 mr-1" aria-hidden="true" />
<span> Delete </span>
</button>
</div>
</div>
</template>

View file

@ -6,8 +6,8 @@
<slot name="title"></slot> <slot name="title"></slot>
<template v-if="collapsable"> <template v-if="collapsable">
<span class="ml-2 swap swap-rotate" :class="`${collapsed ? 'swap-active' : ''}`"> <span class="ml-2 swap swap-rotate" :class="`${collapsed ? 'swap-active' : ''}`">
<Icon class="h-6 w-6 swap-on" name="mdi-chevron-right" /> <MdiChevronRight class="h-6 w-6 swap-on" />
<Icon class="h-6 w-6 swap-off" name="mdi-chevron-down" /> <MdiChevronDown class="h-6 w-6 swap-off" />
</span> </span>
</template> </template>
</h3> </h3>
@ -34,6 +34,9 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import MdiChevronDown from "~icons/mdi/chevron-down";
import MdiChevronRight from "~icons/mdi/chevron-right";
defineProps<{ defineProps<{
collapsable?: boolean; collapsable?: boolean;
}>(); }>();

View file

@ -1,7 +1,7 @@
<template> <template>
<div class="pb-3"> <div class="pb-3">
<h3 <h3
class="text-3xl font-bold tracking-tight" class="text-3xl font-bold tracking-tight flex items-center"
:class="{ :class="{
'text-neutral-content': dark, 'text-neutral-content': dark,
'text-content': !dark, 'text-content': !dark,

View file

@ -16,10 +16,10 @@
class="absolute inset-y-0 right-6 flex items-center rounded-r-md px-2 focus:outline-none" class="absolute inset-y-0 right-6 flex items-center rounded-r-md px-2 focus:outline-none"
@click="clear" @click="clear"
> >
<Icon name="mdi-close" class="w-5 h-5" /> <MdiClose class="w-5 h-5" />
</button> </button>
<ComboboxButton class="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none"> <ComboboxButton class="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none">
<Icon name="mdi-chevron-down" class="w-5 h-5" /> <MdiChevronDown class="w-5 h-5" />
</ComboboxButton> </ComboboxButton>
<ComboboxOptions <ComboboxOptions
v-if="computedItems.length > 0" v-if="computedItems.length > 0"
@ -49,7 +49,7 @@
active ? 'text-primary-content' : 'bg-primary', active ? 'text-primary-content' : 'bg-primary',
]" ]"
> >
<Icon name="mdi-check" class="h-5 w-5" aria-hidden="true" /> <MdiCheck class="h-5 w-5" aria-hidden="true" />
</span> </span>
</slot> </slot>
</li> </li>
@ -70,6 +70,9 @@
ComboboxButton, ComboboxButton,
ComboboxLabel, ComboboxLabel,
} from "@headlessui/vue"; } from "@headlessui/vue";
import MdiClose from "~icons/mdi/close";
import MdiChevronDown from "~icons/mdi/chevron-down";
import MdiCheck from "~icons/mdi/check";
type SupportValues = string | { [key: string]: any }; type SupportValues = string | { [key: string]: any };

View file

@ -7,12 +7,14 @@
data-tip="Toggle Password Show" data-tip="Toggle Password Show"
@click="toggle()" @click="toggle()"
> >
<Icon name="mdi-eye" class="h-5 w-5" /> <MdiEye name="mdi-eye" class="h-5 w-5" />
</button> </button>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import MdiEye from "~icons/mdi/eye";
type Props = { type Props = {
modelValue: string; modelValue: string;
placeholder?: string; placeholder?: string;

View file

@ -1,31 +0,0 @@
<script setup lang="ts">
import type { Ref } from "vue";
import type { IconifyIcon } from "@iconify/vue";
import { Icon as Iconify, loadIcon } from "@iconify/vue";
const nuxtApp = useNuxtApp();
const props = defineProps({
name: {
type: String,
required: true,
},
});
const icon: Ref<IconifyIcon | null> = ref(null);
const component = computed(() => nuxtApp.vueApp.component(props.name));
icon.value = await loadIcon(props.name).catch(() => null);
watch(
() => props.name,
async () => {
icon.value = await loadIcon(props.name).catch(() => null);
}
);
</script>
<template>
<Iconify v-if="icon" :icon="icon" class="inline-block" />
<Component :is="component" v-else-if="component" />
<span v-else>{{ name }}</span>
</template>

View file

@ -6,15 +6,15 @@
class="flex items-center justify-between py-3 pl-3 pr-4 text-sm" class="flex items-center justify-between py-3 pl-3 pr-4 text-sm"
> >
<div class="flex w-0 flex-1 items-center"> <div class="flex w-0 flex-1 items-center">
<Icon name="mdi-paperclip" class="h-5 w-5 flex-shrink-0 text-gray-400" aria-hidden="true" /> <MdiPaperclip class="h-5 w-5 flex-shrink-0 text-gray-400" aria-hidden="true" />
<span class="ml-2 w-0 flex-1 truncate"> {{ attachment.document.title }}</span> <span class="ml-2 w-0 flex-1 truncate"> {{ attachment.document.title }}</span>
</div> </div>
<div class="ml-4 flex-shrink-0"> <div class="ml-4 flex-shrink-0">
<a class="tooltip mr-2" data-tip="Download" :href="attachmentURL(attachment.id)" target="_blank"> <a class="tooltip mr-2" data-tip="Download" :href="attachmentURL(attachment.id)" target="_blank">
<Icon class="h-5 w-5" name="mdi-download" /> <MdiDownload class="h-5 w-5" />
</a> </a>
<a class="tooltip" data-tip="Open" :href="attachmentURL(attachment.id)" target="_blank"> <a class="tooltip" data-tip="Open" :href="attachmentURL(attachment.id)" target="_blank">
<Icon class="h-5 w-5" name="mdi-open-in-new" /> <MdiOpenInNew class="h-5 w-5" />
</a> </a>
</div> </div>
</li> </li>
@ -23,6 +23,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { ItemAttachment } from "~~/lib/api/types/data-contracts"; import { ItemAttachment } from "~~/lib/api/types/data-contracts";
import MdiPaperclip from "~icons/mdi/paperclip";
import MdiDownload from "~icons/mdi/download";
import MdiOpenInNew from "~icons/mdi/open-in-new";
const props = defineProps({ const props = defineProps({
attachments: { attachments: {

View file

@ -17,7 +17,7 @@
<div class="divider my-0"></div> <div class="divider my-0"></div>
<div class="flex justify-between gap-2"> <div class="flex justify-between gap-2">
<div v-if="item.insured" class="tooltip z-10" data-tip="Insured"> <div v-if="item.insured" class="tooltip z-10" data-tip="Insured">
<Icon class="h-5 w-5 text-primary" name="mdi-shield-check" /> <MdiShieldCheck class="h-5 w-5 text-primary" />
</div> </div>
<div class="tooltip" data-tip="Quantity"> <div class="tooltip" data-tip="Quantity">
<span class="badge h-5 w-5 badge-primary badge-sm text-xs"> <span class="badge h-5 w-5 badge-primary badge-sm text-xs">
@ -35,6 +35,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ItemOut, ItemSummary } from "~~/lib/api/types/data-contracts"; import { ItemOut, ItemSummary } from "~~/lib/api/types/data-contracts";
import MdiShieldCheck from "~icons/mdi/shield-check";
const api = useUserApi(); const api = useUserApi();

View file

@ -10,14 +10,14 @@
<div class="flex justify-center"> <div class="flex justify-center">
<BaseButton class="rounded-r-none" :loading="loading" type="submit"> <BaseButton class="rounded-r-none" :loading="loading" type="submit">
<template #icon> <template #icon>
<Icon name="mdi-package-variant" class="swap-off h-5 w-5" /> <MdiPackageVariant class="swap-off h-5 w-5" />
<Icon name="mdi-package-variant-closed" class="swap-on h-5 w-5" /> <MdiPackageVariantClosed class="swap-on h-5 w-5" />
</template> </template>
Create Create
</BaseButton> </BaseButton>
<div class="dropdown dropdown-top"> <div class="dropdown dropdown-top">
<label tabindex="0" class="btn rounded-l-none rounded-r-xl"> <label tabindex="0" class="btn rounded-l-none rounded-r-xl">
<Icon class="h-5 w-5" name="mdi-chevron-down" /> <MdiChevronDown class="h-5 w-5" name="mdi-chevron-down" />
</label> </label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0"> <ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0">
<li> <li>
@ -38,6 +38,9 @@
import { ItemCreate, LabelOut, LocationOut } from "~~/lib/api/types/data-contracts"; import { ItemCreate, LabelOut, LocationOut } from "~~/lib/api/types/data-contracts";
import { useLabelStore } from "~~/stores/labels"; import { useLabelStore } from "~~/stores/labels";
import { useLocationStore } from "~~/stores/locations"; import { useLocationStore } from "~~/stores/locations";
import MdiPackageVariant from "~icons/mdi/package-variant";
import MdiPackageVariantClosed from "~icons/mdi/package-variant-closed";
import MdiChevronDown from "~icons/mdi/chevron-down";
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {

View file

@ -1,6 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { ViewType } from "~~/composables/use-preferences"; import { ViewType } from "~~/composables/use-preferences";
import { ItemSummary } from "~~/lib/api/types/data-contracts"; import { ItemSummary } from "~~/lib/api/types/data-contracts";
import MdiDotsVertical from "~icons/mdi/dots-vertical";
import MdiCardTextOutline from "~icons/mdi/card-text-outline";
import MdiTable from "~icons/mdi/table";
type Props = { type Props = {
view?: ViewType; view?: ViewType;
@ -30,18 +33,18 @@
<template #description> <template #description>
<div v-if="!viewSet" class="dropdown dropdown-hover dropdown-left"> <div v-if="!viewSet" class="dropdown dropdown-hover dropdown-left">
<label tabindex="0" class="btn btn-ghost m-1"> <label tabindex="0" class="btn btn-ghost m-1">
<Icon name="mdi-dots-vertical" class="h-7 w-7" /> <MdiDotsVertical class="h-7 w-7" />
</label> </label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-32"> <ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-32">
<li> <li>
<button @click="setViewPreference('card')"> <button @click="setViewPreference('card')">
<Icon name="mdi-card-text-outline" class="h-5 w-5" /> <MdiCardTextOutline class="h-5 w-5" />
Card Card
</button> </button>
</li> </li>
<li> <li>
<button @click="setViewPreference('table')"> <button @click="setViewPreference('table')">
<Icon name="mdi-table" class="h-5 w-5" /> <MdiTable class="h-5 w-5" />
Table Table
</button> </button>
</li> </li>

View file

@ -19,10 +19,13 @@
> >
<template v-if="typeof h === 'string'">{{ h }}</template> <template v-if="typeof h === 'string'">{{ h }}</template>
<template v-else>{{ h.text }}</template> <template v-else>{{ h.text }}</template>
<div :class="`inline-flex ${sortByProperty === h.value ? '' : 'opacity-0'}`"> <div
v-if="sortByProperty === h.value"
:class="`inline-flex ${sortByProperty === h.value ? '' : 'opacity-0'}`"
>
<span class="swap swap-rotate" :class="{ 'swap-active': pagination.descending }"> <span class="swap swap-rotate" :class="{ 'swap-active': pagination.descending }">
<Icon name="mdi-arrow-down" class="swap-on h-5 w-5" /> <MdiArrowDown class="swap-on h-5 w-5" />
<Icon name="mdi-arrow-up" class="swap-off h-5 w-5" /> <MdiArrowUp class="swap-off h-5 w-5" />
</span> </span>
</div> </div>
</div> </div>
@ -50,8 +53,8 @@
<Currency :amount="d.purchasePrice" /> <Currency :amount="d.purchasePrice" />
</template> </template>
<template v-else-if="cell(h) === 'cell-insured'"> <template v-else-if="cell(h) === 'cell-insured'">
<Icon v-if="d.insured" name="mdi-check" class="text-green-500 h-5 w-5" /> <MdiCheck v-if="d.insured" class="text-green-500 h-5 w-5 inline" />
<Icon v-else name="mdi-close" class="text-red-500 h-5 w-5" /> <MdiClose v-else class="text-red-500 h-5 w-5 inline" />
</template> </template>
<slot v-else :name="cell(h)" v-bind="{ item: d }"> <slot v-else :name="cell(h)" v-bind="{ item: d }">
{{ extractValue(d, h.value) }} {{ extractValue(d, h.value) }}
@ -73,6 +76,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { TableData, TableHeader } from "./Table.types"; import { TableData, TableHeader } from "./Table.types";
import { ItemSummary } from "~~/lib/api/types/data-contracts"; import { ItemSummary } from "~~/lib/api/types/data-contracts";
import MdiArrowDown from "~icons/mdi/arrow-down";
import MdiArrowUp from "~icons/mdi/arrow-up";
import MdiCheck from "~icons/mdi/check";
import MdiClose from "~icons/mdi/close";
type Props = { type Props = {
items: ItemSummary[]; items: ItemSummary[];

View file

@ -1,5 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { LabelOut, LabelSummary } from "~~/lib/api/types/data-contracts"; import { LabelOut, LabelSummary } from "~~/lib/api/types/data-contracts";
import MdiArrowRight from "~icons/mdi/arrow-right";
import MdiTagOutline from "~icons/mdi/tag-outline";
export type sizes = "sm" | "md" | "lg" | "xl"; export type sizes = "sm" | "md" | "lg" | "xl";
defineProps({ defineProps({
@ -32,8 +34,8 @@
:to="`/label/${label.id}`" :to="`/label/${label.id}`"
> >
<label class="swap swap-rotate" :class="isActive ? 'swap-active' : ''"> <label class="swap swap-rotate" :class="isActive ? 'swap-active' : ''">
<Icon name="heroicons-arrow-right" class="mr-2 swap-on"></Icon> <MdiArrowRight class="mr-2 swap-on" />
<Icon name="heroicons-tag" class="mr-2 swap-off"></Icon> <MdiTagOutline class="mr-2 swap-off" />
</label> </label>
{{ label.name }} {{ label.name }}
</NuxtLink> </NuxtLink>

View file

@ -15,7 +15,7 @@
<BaseButton class="rounded-r-none" :loading="loading" type="submit"> Create </BaseButton> <BaseButton class="rounded-r-none" :loading="loading" type="submit"> Create </BaseButton>
<div class="dropdown dropdown-top"> <div class="dropdown dropdown-top">
<label tabindex="0" class="btn rounded-l-none rounded-r-xl"> <label tabindex="0" class="btn rounded-l-none rounded-r-xl">
<Icon class="h-5 w-5" name="mdi-chevron-down" /> <MdiChevronDown class="h-5 w-5" />
</label> </label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0"> <ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0">
<li> <li>
@ -33,6 +33,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import MdiChevronDown from "~icons/mdi/chevron-down";
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
type: Boolean, type: Boolean,

View file

@ -13,18 +13,13 @@
> >
<h2 class="flex items-center justify-between gap-2"> <h2 class="flex items-center justify-between gap-2">
<label class="swap swap-rotate" :class="isActive ? 'swap-active' : ''"> <label class="swap swap-rotate" :class="isActive ? 'swap-active' : ''">
<Icon name="heroicons-arrow-right" class="swap-on h-6 w-6" /> <MdiArrowRight class="swap-on h-6 w-6" />
<Icon name="heroicons-map-pin" class="swap-off h-6 w-6" /> <MdiMapMarkerOutline class="swap-off h-6 w-6" />
</label> </label>
<span class="mx-auto"> <span class="mx-auto">
{{ location.name }} {{ location.name }}
</span> </span>
<span <span class="badge badge-primary h-6 badge-lg" :class="{ 'opacity-0': !hasCount }">
class="badge badge-primary h-6 badge-lg"
:class="{
'opacity-0': !hasCount,
}"
>
{{ count }} {{ count }}
</span> </span>
</h2> </h2>
@ -34,6 +29,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import { LocationOut, LocationOutCount, LocationSummary } from "~~/lib/api/types/data-contracts"; import { LocationOut, LocationOutCount, LocationSummary } from "~~/lib/api/types/data-contracts";
import MdiArrowRight from "~icons/mdi/arrow-right";
import MdiMapMarkerOutline from "~icons/mdi/map-marker-outline";
const props = defineProps({ const props = defineProps({
location: { location: {

View file

@ -16,7 +16,7 @@
<BaseButton class="rounded-r-none" type="submit" :loading="loading"> Create </BaseButton> <BaseButton class="rounded-r-none" type="submit" :loading="loading"> Create </BaseButton>
<div class="dropdown dropdown-top"> <div class="dropdown dropdown-top">
<label tabindex="0" class="btn rounded-l-none rounded-r-xl"> <label tabindex="0" class="btn rounded-l-none rounded-r-xl">
<Icon class="h-5 w-5" name="mdi-chevron-down" /> <MdiChevronDown class="h-5 w-5" />
</label> </label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0"> <ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0">
<li> <li>
@ -35,6 +35,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { LocationSummary } from "~~/lib/api/types/data-contracts"; import { LocationSummary } from "~~/lib/api/types/data-contracts";
import MdiChevronDown from "~icons/mdi/chevron-down";
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
type: Boolean, type: Boolean,

View file

@ -8,7 +8,7 @@
v-if="selected" v-if="selected"
:class="['absolute inset-y-0 right-0 flex items-center pr-4', active ? 'text-white' : 'text-primary']" :class="['absolute inset-y-0 right-0 flex items-center pr-4', active ? 'text-white' : 'text-primary']"
> >
<Icon name="mdi-check" class="h-5 w-5" aria-hidden="true" /> <MdiCheck class="h-5 w-5" aria-hidden="true" />
</span> </span>
</div> </div>
<div v-if="cast(item.value).name != cast(item.value).treeString" class="text-xs mt-1"> <div v-if="cast(item.value).name != cast(item.value).treeString" class="text-xs mt-1">
@ -22,6 +22,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { FlatTreeItem, useFlatLocations } from "~~/composables/use-location-helpers"; import { FlatTreeItem, useFlatLocations } from "~~/composables/use-location-helpers";
import { LocationSummary } from "~~/lib/api/types/data-contracts"; import { LocationSummary } from "~~/lib/api/types/data-contracts";
import MdiCheck from "~icons/mdi/check";
type Props = { type Props = {
modelValue?: LocationSummary | null; modelValue?: LocationSummary | null;

View file

@ -1,6 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { useTreeState } from "./tree-state"; import { useTreeState } from "./tree-state";
import { TreeItem } from "~~/lib/api/types/data-contracts"; import { TreeItem } from "~~/lib/api/types/data-contracts";
import MdiChevronDown from "~icons/mdi/chevron-down";
import MdiChevronRight from "~icons/mdi/chevron-right";
import MdiMapMarker from "~icons/mdi/map-marker";
import MdiPackageVariant from "~icons/mdi/package-variant";
type Props = { type Props = {
treeId: string; treeId: string;
@ -56,12 +60,12 @@
'swap-active': openRef, 'swap-active': openRef,
}" }"
> >
<Icon name="mdi-chevron-right" class="h-6 w-6 swap-off" /> <MdiChevronRight name="mdi-chevron-right" class="h-6 w-6 swap-off" />
<Icon name="mdi-chevron-down" class="h-6 w-6 swap-on" /> <MdiChevronDown name="mdi-chevron-down" class="h-6 w-6 swap-on" />
</label> </label>
</div> </div>
<Icon v-if="item.type === 'location'" name="mdi-map-marker" class="h-4 w-4" /> <MdiMapMarker v-if="item.type === 'location'" class="h-4 w-4" />
<Icon v-else name="mdi-package-variant" class="h-4 w-4" /> <MdiPackageVariant v-else class="h-4 w-4" />
<NuxtLink class="hover:link text-lg" :to="link" @click.stop>{{ item.name }} </NuxtLink> <NuxtLink class="hover:link text-lg" :to="link" @click.stop>{{ item.name }} </NuxtLink>
</div> </div>
<div v-if="openRef" class="ml-4"> <div v-if="openRef" class="ml-4">

View file

@ -1,7 +1,7 @@
<template> <template>
<div ref="el" class="dropdown" :class="{ 'dropdown-open': dropdownOpen }"> <div ref="el" class="dropdown" :class="{ 'dropdown-open': dropdownOpen }">
<button ref="btn" tabindex="0" class="btn btn-xs" @click="toggle"> <button ref="btn" tabindex="0" class="btn btn-xs" @click="toggle">
{{ label }} {{ len }} <Icon name="mdi-chevron-down" class="h-4 w-4" /> {{ label }} {{ len }} <MdiChevronDown class="h-4 w-4" />
</button> </button>
<div tabindex="0" class="dropdown-content mt-1 w-64 shadow bg-base-100 rounded-md"> <div tabindex="0" class="dropdown-content mt-1 w-64 shadow bg-base-100 rounded-md">
<div class="pt-4 px-4 shadow-sm mb-1"> <div class="pt-4 px-4 shadow-sm mb-1">
@ -39,6 +39,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import MdiChevronDown from "~icons/mdi/chevron-down";
type Props = { type Props = {
label: string; label: string;
options: any[]; options: any[];

View file

@ -6,17 +6,15 @@
'swap-active': copied, 'swap-active': copied,
}" }"
> >
<Icon <MdiContentCopy
class="swap-off" class="swap-off"
name="mdi-content-copy"
:style="{ :style="{
height: `${iconSize}px`, height: `${iconSize}px`,
width: `${iconSize}px`, width: `${iconSize}px`,
}" }"
/> />
<Icon <MdiClipboard
class="swap-on" class="swap-on"
name="mdi-clipboard"
:style="{ :style="{
height: `${iconSize}px`, height: `${iconSize}px`,
width: `${iconSize}px`, width: `${iconSize}px`,
@ -27,6 +25,9 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import MdiContentCopy from "~icons/mdi/content-copy";
import MdiClipboard from "~icons/mdi/clipboard";
const props = defineProps({ const props = defineProps({
text: { text: {
type: String as () => string, type: String as () => string,
@ -51,5 +52,3 @@
}, 1000); }, 1000);
} }
</script> </script>
<style scoped></style>

View file

@ -16,7 +16,7 @@
<template v-else-if="detail.type === 'link'"> <template v-else-if="detail.type === 'link'">
<div class="tooltip tooltip-primary tooltip-right" :data-tip="detail.href"> <div class="tooltip tooltip-primary tooltip-right" :data-tip="detail.href">
<a class="btn btn-primary btn-xs" :href="detail.href" target="_blank"> <a class="btn btn-primary btn-xs" :href="detail.href" target="_blank">
<Icon name="mdi-open-in-new" class="mr-2 swap-on"></Icon> <MdiOpenInNew class="mr-2 swap-on" />
{{ detail.text }} {{ detail.text }}
</a> </a>
</div> </div>
@ -51,6 +51,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { AnyDetail, Detail } from "./types"; import type { AnyDetail, Detail } from "./types";
import MdiOpenInNew from "~icons/mdi/open-in-new";
defineProps({ defineProps({
details: { details: {

View file

@ -2,7 +2,7 @@
<div class="dropdown dropdown-left"> <div class="dropdown dropdown-left">
<slot> <slot>
<label tabindex="0" class="btn btn-circle btn-sm"> <label tabindex="0" class="btn btn-circle btn-sm">
<Icon name="mdi-qrcode" /> <MdiQrcode />
</label> </label>
</slot> </slot>
<div tabindex="0" class="card compact dropdown-content shadow-lg bg-base-100 rounded-box w-64"> <div tabindex="0" class="card compact dropdown-content shadow-lg bg-base-100 rounded-box w-64">
@ -16,6 +16,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { route } from "../../lib/api/base"; import { route } from "../../lib/api/base";
import MdiQrcode from "~icons/mdi/qrcode";
function getQRCodeUrl(): string { function getQRCodeUrl(): string {
const currentURL = window.location.href; const currentURL = window.location.href;

1
frontend/global.d.ts vendored Normal file
View file

@ -0,0 +1 @@
/// <reference types="unplugin-icons/types/vue" />

View file

@ -17,7 +17,7 @@
<!-- Button --> <!-- Button -->
<div class="navbar z-[99] lg:hidden top-0 fixed bg-primary shadow-md drawer-button"> <div class="navbar z-[99] lg:hidden top-0 fixed bg-primary shadow-md drawer-button">
<label for="my-drawer-2" class="btn btn-square btn-ghost text-base-100 drawer-button lg:hidden"> <label for="my-drawer-2" class="btn btn-square btn-ghost text-base-100 drawer-button lg:hidden">
<Icon name="mdi-menu" class="h-6 w-6" /> <MdiMenu class="h-6 w-6" />
</label> </label>
<NuxtLink to="/home"> <NuxtLink to="/home">
<h2 class="text-3xl font-bold tracking-tight text-base-100 flex"> <h2 class="text-3xl font-bold tracking-tight text-base-100 flex">
@ -51,7 +51,7 @@
<div class="dropdown overflow visible w-40"> <div class="dropdown overflow visible w-40">
<label tabindex="0" class="btn btn-primary btn-block text-lg text-no-transform"> <label tabindex="0" class="btn btn-primary btn-block text-lg text-no-transform">
<span> <span>
<Icon name="mdi-plus" class="mr-1 -ml-1" /> <MdiPlus class="mr-1 -ml-1" />
</span> </span>
Create Create
</label> </label>
@ -74,7 +74,7 @@
'bg-secondary text-secondary-content': n.active?.value, 'bg-secondary text-secondary-content': n.active?.value,
}" }"
> >
<Icon :name="n.icon" class="h-6 w-6 mr-4" /> <component :is="n.icon" class="h-6 w-6 mr-4" />
{{ n.name }} {{ n.name }}
</NuxtLink> </NuxtLink>
</li> </li>
@ -93,6 +93,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useLabelStore } from "~~/stores/labels"; import { useLabelStore } from "~~/stores/labels";
import { useLocationStore } from "~~/stores/locations"; import { useLocationStore } from "~~/stores/locations";
import MdiMenu from "~icons/mdi/menu";
import MdiPlus from "~icons/mdi/plus";
import MdiHome from "~icons/mdi/home";
import MdiFileTree from "~icons/mdi/file-tree";
import MdiMagnify from "~icons/mdi/magnify";
import MdiAccount from "~icons/mdi/account";
import MdiCog from "~icons/mdi/cog";
const username = computed(() => authCtx.user?.name || "User"); const username = computed(() => authCtx.user?.name || "User");
@ -138,35 +146,35 @@
const nav = [ const nav = [
{ {
icon: "mdi-home", icon: MdiHome,
active: computed(() => route.path === "/home"), active: computed(() => route.path === "/home"),
id: 0, id: 0,
name: "Home", name: "Home",
to: "/home", to: "/home",
}, },
{ {
icon: "mdi-file-tree", icon: MdiFileTree,
id: 4, id: 4,
active: computed(() => route.path === "/locations"), active: computed(() => route.path === "/locations"),
name: "Locations", name: "Locations",
to: "/locations", to: "/locations",
}, },
{ {
icon: "mdi-magnify", icon: MdiMagnify,
id: 3, id: 3,
active: computed(() => route.path === "/items"), active: computed(() => route.path === "/items"),
name: "Search", name: "Search",
to: "/items", to: "/items",
}, },
{ {
icon: "mdi-account", icon: MdiAccount,
id: 1, id: 1,
active: computed(() => route.path === "/profile"), active: computed(() => route.path === "/profile"),
name: "Profile", name: "Profile",
to: "/profile", to: "/profile",
}, },
{ {
icon: "mdi-cog", icon: MdiCog,
id: 6, id: 6,
active: computed(() => route.path === "/tools"), active: computed(() => route.path === "/tools"),
name: "Tools", name: "Tools",

View file

@ -3,7 +3,14 @@ import { defineNuxtConfig } from "nuxt/config";
// https://v3.nuxtjs.org/api/configuration/nuxt.config // https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({ export default defineNuxtConfig({
ssr: false, ssr: false,
modules: ["@nuxtjs/tailwindcss", "@pinia/nuxt", "@vueuse/nuxt", "@vite-pwa/nuxt", "./nuxt.proxyoverride.ts"], modules: [
"@nuxtjs/tailwindcss",
"@pinia/nuxt",
"@vueuse/nuxt",
"@vite-pwa/nuxt",
"./nuxt.proxyoverride.ts",
"unplugin-icons/nuxt",
],
nitro: { nitro: {
devProxy: { devProxy: {
"/api": { "/api": {

View file

@ -15,6 +15,7 @@
}, },
"devDependencies": { "devDependencies": {
"@faker-js/faker": "^8.0.0", "@faker-js/faker": "^8.0.0",
"@iconify-json/mdi": "^1.1.64",
"@nuxtjs/eslint-config-typescript": "^12.0.0", "@nuxtjs/eslint-config-typescript": "^12.0.0",
"@types/dompurify": "^3.0.0", "@types/dompurify": "^3.0.0",
"@types/markdown-it": "^13.0.0", "@types/markdown-it": "^13.0.0",
@ -30,12 +31,12 @@
"nuxt": "3.6.5", "nuxt": "3.6.5",
"prettier": "^2.7.1", "prettier": "^2.7.1",
"typescript": "^5.0.0", "typescript": "^5.0.0",
"unplugin-icons": "^0.18.5",
"vite-plugin-eslint": "^1.8.1", "vite-plugin-eslint": "^1.8.1",
"vitest": "^1.0.0" "vitest": "^1.0.0"
}, },
"dependencies": { "dependencies": {
"@headlessui/vue": "^1.7.9", "@headlessui/vue": "^1.7.9",
"@iconify/vue": "^3.2.1",
"@nuxtjs/tailwindcss": "^6.1.3", "@nuxtjs/tailwindcss": "^6.1.3",
"@pinia/nuxt": "^0.5.0", "@pinia/nuxt": "^0.5.0",
"@tailwindcss/aspect-ratio": "^0.4.0", "@tailwindcss/aspect-ratio": "^0.4.0",

View file

@ -1,4 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import MdiGithub from "~icons/mdi/github";
import MdiTwitter from "~icons/mdi/twitter";
import MdiDiscord from "~icons/mdi/discord";
import MdiFolder from "~icons/mdi/folder";
import MdiAccount from "~icons/mdi/account";
import MdiAccountPlus from "~icons/mdi/account-plus";
import MdiLogin from "~icons/mdi/login";
import MdiArrowRight from "~icons/mdi/arrow-right";
import MdiLock from "~icons/mdi/lock";
useHead({ useHead({
title: "Homebox | Organize and Tag Your Stuff", title: "Homebox | Organize and Tag Your Stuff",
}); });
@ -141,16 +151,16 @@
</div> </div>
<div class="flex mt-6 sm:mt-0 gap-4 ml-auto text-neutral-content"> <div class="flex mt-6 sm:mt-0 gap-4 ml-auto text-neutral-content">
<a class="tooltip" data-tip="Project Github" href="https://github.com/hay-kot/homebox" target="_blank"> <a class="tooltip" data-tip="Project Github" href="https://github.com/hay-kot/homebox" target="_blank">
<Icon name="mdi-github" class="h-8 w-8" /> <MdiGithub class="h-8 w-8" />
</a> </a>
<a href="https://twitter.com/haybytes" class="tooltip" data-tip="Follow The Developer" target="_blank"> <a href="https://twitter.com/haybytes" class="tooltip" data-tip="Follow The Developer" target="_blank">
<Icon name="mdi-twitter" class="h-8 w-8" /> <MdiTwitter class="h-8 w-8" />
</a> </a>
<a href="https://discord.gg/tuncmNrE4z" class="tooltip" data-tip="Join The Discord" target="_blank"> <a href="https://discord.gg/tuncmNrE4z" class="tooltip" data-tip="Join The Discord" target="_blank">
<Icon name="mdi-discord" class="h-8 w-8" /> <MdiDiscord class="h-8 w-8" />
</a> </a>
<a href="https://hay-kot.github.io/homebox/" class="tooltip" data-tip="Read The Docs" target="_blank"> <a href="https://hay-kot.github.io/homebox/" class="tooltip" data-tip="Read The Docs" target="_blank">
<Icon name="mdi-folder" class="h-8 w-8" /> <MdiFolder class="h-8 w-8" />
</a> </a>
</div> </div>
</header> </header>
@ -161,7 +171,7 @@
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl"> <div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
<div class="card-body"> <div class="card-body">
<h2 class="card-title text-2xl align-center"> <h2 class="card-title text-2xl align-center">
<Icon name="heroicons-user" class="mr-1 w-7 h-7" /> <MdiAccount class="mr-1 w-7 h-7" />
Register Register
</h2> </h2>
<FormTextField v-model="email" label="Set your email?" /> <FormTextField v-model="email" label="Set your email?" />
@ -191,7 +201,7 @@
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl"> <div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
<div class="card-body"> <div class="card-body">
<h2 class="card-title text-2xl align-center"> <h2 class="card-title text-2xl align-center">
<Icon name="heroicons-user" class="mr-1 w-7 h-7" /> <MdiAccount class="mr-1 w-7 h-7" />
Login Login
</h2> </h2>
<template v-if="status && status.demo"> <template v-if="status && status.demo">
@ -225,14 +235,14 @@
@click="() => toggleLogin()" @click="() => toggleLogin()"
> >
<template #icon> <template #icon>
<Icon v-if="!registerForm" name="mdi-account-plus-outline" class="w-5 h-5 swap-off" /> <MdiAccountPlus v-if="!registerForm" class="w-5 h-5 swap-off" />
<Icon v-else name="mdi-login" class="w-5 h-5 swap-off" /> <MdiLogin v-else class="w-5 h-5 swap-off" />
<Icon name="mdi-arrow-right" class="w-5 h-5 swap-on" /> <MdiArrowRight class="w-5 h-5 swap-on" />
</template> </template>
{{ registerForm ? "Login" : "Register" }} {{ registerForm ? "Login" : "Register" }}
</BaseButton> </BaseButton>
<p v-else class="text-base-content italic text-sm inline-flex items-center gap-2"> <p v-else class="text-base-content italic text-sm inline-flex items-center gap-2">
<Icon name="mdi-lock" class="w-4 h-4 inline-block" /> <MdiLock class="w-4 h-4 inline-block" />
Registration Disabled Registration Disabled
</p> </p>
</div> </div>

View file

@ -1,6 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { AnyDetail, Detail, Details, filterZeroValues } from "~~/components/global/DetailsSection/types"; import { AnyDetail, Detail, Details, filterZeroValues } from "~~/components/global/DetailsSection/types";
import { ItemAttachment } from "~~/lib/api/types/data-contracts"; import { ItemAttachment } from "~~/lib/api/types/data-contracts";
import MdiClose from "~icons/mdi/close";
import MdiPackageVariant from "~icons/mdi/package-variant";
import MdiPlus from "~icons/mdi/plus";
import MdiMinus from "~icons/mdi/minus";
import MdiDownload from "~icons/mdi/download";
definePageMeta({ definePageMeta({
middleware: ["auth"], middleware: ["auth"],
@ -439,10 +444,10 @@
<div ref="refDialogBody" class="relative"> <div ref="refDialogBody" class="relative">
<div class="absolute right-0 -mt-3 -mr-3 sm:-mt-4 sm:-mr-4 space-x-1"> <div class="absolute right-0 -mt-3 -mr-3 sm:-mt-4 sm:-mr-4 space-x-1">
<a class="btn btn-sm sm:btn-md btn-primary btn-circle" :href="dialoged.src" download> <a class="btn btn-sm sm:btn-md btn-primary btn-circle" :href="dialoged.src" download>
<Icon class="h-5 w-5" name="mdi-download" /> <MdiDownload class="h-5 w-5" />
</a> </a>
<button class="btn btn-sm sm:btn-md btn-primary btn-circle" @click="closeDialog()"> <button class="btn btn-sm sm:btn-md btn-primary btn-circle" @click="closeDialog()">
<Icon class="h-5 w-5" name="mdi-close" /> <MdiClose class="h-5 w-5" />
</button> </button>
</div> </div>
@ -456,7 +461,7 @@
<div class="flex flex-wrap items-end gap-2"> <div class="flex flex-wrap items-end gap-2">
<div class="avatar placeholder mb-auto"> <div class="avatar placeholder mb-auto">
<div class="bg-neutral-focus text-neutral-content rounded-full w-12"> <div class="bg-neutral-focus text-neutral-content rounded-full w-12">
<Icon name="mdi-package-variant" class="h-7 w-7" /> <MdiPackageVariant class="h-7 w-7" />
</div> </div>
</div> </div>
<div> <div>
@ -525,10 +530,10 @@
class="opacity-0 group-hover:opacity-100 ml-4 my-0 duration-75 transition-opacity inline-flex gap-2" class="opacity-0 group-hover:opacity-100 ml-4 my-0 duration-75 transition-opacity inline-flex gap-2"
> >
<button class="btn btn-circle btn-xs" @click="adjustQuantity(-1)"> <button class="btn btn-circle btn-xs" @click="adjustQuantity(-1)">
<Icon name="mdi-minus" class="h-3 w-3" /> <MdiMinus class="h-3 w-3" />
</button> </button>
<button class="btn btn-circle btn-xs" @click="adjustQuantity(1)"> <button class="btn btn-circle btn-xs" @click="adjustQuantity(1)">
<Icon name="mdi-plus" class="h-3 w-3" /> <MdiPlus class="h-3 w-3" />
</button> </button>
</span> </span>
</template> </template>

View file

@ -5,6 +5,9 @@
import { useLocationStore } from "~~/stores/locations"; import { useLocationStore } from "~~/stores/locations";
import { capitalize } from "~~/lib/strings"; import { capitalize } from "~~/lib/strings";
import Autocomplete from "~~/components/Form/Autocomplete.vue"; import Autocomplete from "~~/components/Form/Autocomplete.vue";
import MdiDelete from "~icons/mdi/delete";
import MdiPencil from "~icons/mdi/pencil";
import MdiContentSaveOutline from "~icons/mdi/content-save-outline";
definePageMeta({ definePageMeta({
middleware: ["auth"], middleware: ["auth"],
@ -445,12 +448,12 @@
</div> </div>
<BaseButton size="sm" @click="saveItem"> <BaseButton size="sm" @click="saveItem">
<template #icon> <template #icon>
<Icon name="mdi-content-save-outline" /> <MdiContentSaveOutline />
</template> </template>
Save Save
</BaseButton> </BaseButton>
<BaseButton class="btn btn-sm btn-error" @click="deleteItem()"> <BaseButton class="btn btn-sm btn-error" @click="deleteItem()">
<Icon name="mdi-delete" class="mr-2" /> <MdiDelete class="mr-2" />
Delete Delete
</BaseButton> </BaseButton>
</div> </div>
@ -522,7 +525,7 @@
<FormTextField v-model="field.textValue" label="Value" /> <FormTextField v-model="field.textValue" label="Value" />
<div class="tooltip" data-tip="Delete"> <div class="tooltip" data-tip="Delete">
<button class="btn btn-sm btn-square mb-2 ml-2" @click="item.fields.splice(idx, 1)"> <button class="btn btn-sm btn-square mb-2 ml-2" @click="item.fields.splice(idx, 1)">
<Icon name="mdi-delete" /> <MdiDelete />
</button> </button>
</div> </div>
</div> </div>
@ -576,12 +579,12 @@
<div class="flex gap-2 justify-end"> <div class="flex gap-2 justify-end">
<div class="tooltip" data-tip="Delete"> <div class="tooltip" data-tip="Delete">
<button class="btn btn-sm btn-square" @click="deleteAttachment(attachment.id)"> <button class="btn btn-sm btn-square" @click="deleteAttachment(attachment.id)">
<Icon name="mdi-delete" /> <MdiDelete />
</button> </button>
</div> </div>
<div class="tooltip" data-tip="Edit"> <div class="tooltip" data-tip="Edit">
<button class="btn btn-sm btn-square" @click="openAttachmentEditDialog(attachment)"> <button class="btn btn-sm btn-square" @click="openAttachmentEditDialog(attachment)">
<Icon name="mdi-pencil" /> <MdiPencil />
</button> </button>
</div> </div>
</div> </div>

View file

@ -2,6 +2,13 @@
import DatePicker from "~~/components/Form/DatePicker.vue"; import DatePicker from "~~/components/Form/DatePicker.vue";
import { StatsFormat } from "~~/components/global/StatCard/types"; import { StatsFormat } from "~~/components/global/StatCard/types";
import { ItemOut, MaintenanceEntry } from "~~/lib/api/types/data-contracts"; import { ItemOut, MaintenanceEntry } from "~~/lib/api/types/data-contracts";
import MdiPost from "~icons/mdi/post";
import MdiPlus from "~icons/mdi/plus";
import MdiCheck from "~icons/mdi/check";
import MdiDelete from "~icons/mdi/delete";
import MdiEdit from "~icons/mdi/edit";
import MdiCalendar from "~icons/mdi/calendar";
import MdiWrenchClock from "~icons/mdi/wrench-clock";
const props = defineProps<{ const props = defineProps<{
item: ItemOut; item: ItemOut;
@ -184,7 +191,7 @@
<div class="py-2 flex justify-end"> <div class="py-2 flex justify-end">
<BaseButton type="submit" class="ml-2 mt-2"> <BaseButton type="submit" class="ml-2 mt-2">
<template #icon> <template #icon>
<Icon name="mdi-post" /> <MdiPost />
</template> </template>
{{ entry.id ? "Update" : "Create" }} {{ entry.id ? "Update" : "Create" }}
</BaseButton> </BaseButton>
@ -214,7 +221,7 @@
</div> </div>
<BaseButton class="ml-auto" size="sm" @click="newEntry()"> <BaseButton class="ml-auto" size="sm" @click="newEntry()">
<template #icon> <template #icon>
<Icon name="mdi-plus" /> <MdiPlus />
</template> </template>
New New
</BaseButton> </BaseButton>
@ -228,11 +235,11 @@
<template #description> <template #description>
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
<div v-if="validDate(e.completedDate)" class="badge p-3"> <div v-if="validDate(e.completedDate)" class="badge p-3">
<Icon name="mdi-check" class="mr-2" /> <MdiCheck class="mr-2" />
<DateTime :date="e.completedDate" format="human" datetime-type="date" /> <DateTime :date="e.completedDate" format="human" datetime-type="date" />
</div> </div>
<div v-else-if="validDate(e.scheduledDate)" class="badge p-3"> <div v-else-if="validDate(e.scheduledDate)" class="badge p-3">
<Icon name="mdi-calendar" class="mr-2" /> <MdiCalendar class="mr-2" />
<DateTime :date="e.scheduledDate" format="human" datetime-type="date" /> <DateTime :date="e.scheduledDate" format="human" datetime-type="date" />
</div> </div>
<div class="tooltip tooltip-primary" data-tip="Cost"> <div class="tooltip tooltip-primary" data-tip="Cost">
@ -249,13 +256,13 @@
<div class="flex justify-end p-4 gap-1"> <div class="flex justify-end p-4 gap-1">
<BaseButton size="sm" @click="openEditDialog(e)"> <BaseButton size="sm" @click="openEditDialog(e)">
<template #icon> <template #icon>
<Icon name="mdi-edit" /> <MdiEdit />
</template> </template>
Edit Edit
</BaseButton> </BaseButton>
<BaseButton size="sm" @click="deleteEntry(e.id)"> <BaseButton size="sm" @click="deleteEntry(e.id)">
<template #icon> <template #icon>
<Icon name="mdi-delete" /> <MdiDelete />
</template> </template>
Delete Delete
</BaseButton> </BaseButton>
@ -267,7 +274,7 @@
class="relative block w-full rounded-lg border-2 border-dashed border-base-content p-12 text-center" class="relative block w-full rounded-lg border-2 border-dashed border-base-content p-12 text-center"
@click="newEntry()" @click="newEntry()"
> >
<Icon name="mdi-wrench-clock" class="h-16 w-16"></Icon> <MdiWrenchClock class="h-16 w-16 inline" />
<span class="mt-2 block text-sm font-medium text-gray-900"> Create Your First Entry </span> <span class="mt-2 block text-sm font-medium text-gray-900"> Create Your First Entry </span>
</button> </button>
</div> </div>

View file

@ -2,6 +2,11 @@
import { ItemSummary, LabelSummary, LocationOutCount } from "~~/lib/api/types/data-contracts"; import { ItemSummary, LabelSummary, LocationOutCount } from "~~/lib/api/types/data-contracts";
import { useLabelStore } from "~~/stores/labels"; import { useLabelStore } from "~~/stores/labels";
import { useLocationStore } from "~~/stores/locations"; import { useLocationStore } from "~~/stores/locations";
import MdiLoading from "~icons/mdi/loading";
import MdiMagnify from "~icons/mdi/magnify";
import MdiDelete from "~icons/mdi/delete";
import MdiChevronRight from "~icons/mdi/chevron-right";
import MdiChevronLeft from "~icons/mdi/chevron-left";
definePageMeta({ definePageMeta({
middleware: ["auth"], middleware: ["auth"],
@ -319,8 +324,8 @@
</div> </div>
<BaseButton class="btn-block md:w-auto" @click.prevent="submit"> <BaseButton class="btn-block md:w-auto" @click.prevent="submit">
<template #icon> <template #icon>
<Icon v-if="loading" name="mdi-loading" class="animate-spin" /> <MdiLoading v-if="loading" class="animate-spin" />
<Icon v-else name="mdi-search" /> <MdiMagnify v-else />
</template> </template>
Search Search
</BaseButton> </BaseButton>
@ -408,7 +413,7 @@
class="btn btn-square btn-sm md:ml-0 ml-auto mt-auto mb-2" class="btn btn-square btn-sm md:ml-0 ml-auto mt-auto mb-2"
@click="fieldTuples.splice(idx, 1)" @click="fieldTuples.splice(idx, 1)"
> >
<Icon name="mdi-trash" class="w-5 h-5" /> <MdiDelete class="w-5 h-5" />
</button> </button>
</div> </div>
<BaseButton type="button" class="btn-sm mt-2" @click="() => fieldTuples.push(['', ''])"> Add</BaseButton> <BaseButton type="button" class="btn-sm mt-2" @click="() => fieldTuples.push(['', ''])"> Add</BaseButton>
@ -431,14 +436,14 @@
<div class="flex"> <div class="flex">
<div class="btn-group"> <div class="btn-group">
<button :disabled="!hasPrev" class="btn text-no-transform" @click="prev"> <button :disabled="!hasPrev" class="btn text-no-transform" @click="prev">
<Icon class="mr-1 h-6 w-6" name="mdi-chevron-left" /> <MdiChevronLeft class="mr-1 h-6 w-6" name="mdi-chevron-left" />
Prev Prev
</button> </button>
<button v-if="hasPrev" class="btn text-no-transform" @click="page = 1">First</button> <button v-if="hasPrev" class="btn text-no-transform" @click="page = 1">First</button>
<button v-if="hasNext" class="btn text-no-transform" @click="page = totalPages">Last</button> <button v-if="hasNext" class="btn text-no-transform" @click="page = totalPages">Last</button>
<button :disabled="!hasNext" class="btn text-no-transform" @click="next"> <button :disabled="!hasNext" class="btn text-no-transform" @click="next">
Next Next
<Icon class="ml-1 h-6 w-6" name="mdi-chevron-right" /> <MdiChevronRight class="ml-1 h-6 w-6" name="mdi-chevron-right" />
</button> </button>
</div> </div>
</div> </div>

View file

@ -1,4 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import MdiPackageVariant from "~icons/mdi/package-variant";
import MdiPencil from "~icons/mdi/pencil";
import MdiDelete from "~icons/mdi/delete";
definePageMeta({ definePageMeta({
middleware: ["auth"], middleware: ["auth"],
}); });
@ -107,7 +111,7 @@
<div class="flex flex-wrap items-end gap-2"> <div class="flex flex-wrap items-end gap-2">
<div class="avatar placeholder mb-auto"> <div class="avatar placeholder mb-auto">
<div class="bg-neutral-focus text-neutral-content rounded-full w-12"> <div class="bg-neutral-focus text-neutral-content rounded-full w-12">
<Icon name="mdi-package-variant" class="h-7 w-7" /> <MdiPackageVariant class="h-7 w-7" />
</div> </div>
</div> </div>
<div> <div>
@ -125,12 +129,12 @@
<div class="btn-group"> <div class="btn-group">
<PageQRCode class="dropdown-left" /> <PageQRCode class="dropdown-left" />
<BaseButton size="sm" @click="openUpdate"> <BaseButton size="sm" @click="openUpdate">
<Icon class="mr-1" name="mdi-pencil" /> <MdiPencil class="mr-1" />
Edit Edit
</BaseButton> </BaseButton>
</div> </div>
<BaseButton class="btn btn-sm" @click="confirmDelete()"> <BaseButton class="btn btn-sm" @click="confirmDelete()">
<Icon name="mdi-delete" class="mr-2" /> <MdiDelete class="mr-2" />
Delete Delete
</BaseButton> </BaseButton>
</div> </div>

View file

@ -1,6 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { LocationSummary, LocationUpdate } from "~~/lib/api/types/data-contracts"; import { LocationSummary, LocationUpdate } from "~~/lib/api/types/data-contracts";
import { useLocationStore } from "~~/stores/locations"; import { useLocationStore } from "~~/stores/locations";
import MdiPackageVariant from "~icons/mdi/package-variant";
import MdiPencil from "~icons/mdi/pencil";
import MdiDelete from "~icons/mdi/delete";
definePageMeta({ definePageMeta({
middleware: ["auth"], middleware: ["auth"],
@ -123,7 +126,7 @@
<div class="flex flex-wrap items-end gap-2"> <div class="flex flex-wrap items-end gap-2">
<div class="avatar placeholder mb-auto"> <div class="avatar placeholder mb-auto">
<div class="bg-neutral-focus text-neutral-content rounded-full w-12"> <div class="bg-neutral-focus text-neutral-content rounded-full w-12">
<Icon name="mdi-package-variant" class="h-7 w-7" /> <MdiPackageVariant name="mdi-package-variant" class="h-7 w-7" />
</div> </div>
</div> </div>
<div> <div>
@ -149,12 +152,12 @@
<div class="btn-group"> <div class="btn-group">
<PageQRCode class="dropdown-left" /> <PageQRCode class="dropdown-left" />
<BaseButton size="sm" @click="openUpdate"> <BaseButton size="sm" @click="openUpdate">
<Icon class="mr-1" name="mdi-pencil" /> <MdiPencil class="mr-1" name="mdi-pencil" />
Edit Edit
</BaseButton> </BaseButton>
</div> </div>
<BaseButton class="btn btn-sm" @click="confirmDelete()"> <BaseButton class="btn btn-sm" @click="confirmDelete()">
<Icon name="mdi-delete" class="mr-2" /> <MdiDelete name="mdi-delete" class="mr-2" />
Delete Delete
</BaseButton> </BaseButton>
</div> </div>

View file

@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { useTreeState } from "~~/components/Location/Tree/tree-state"; import { useTreeState } from "~~/components/Location/Tree/tree-state";
import MdiCollapseAllOutline from "~icons/mdi/collapse-all-outline";
definePageMeta({ definePageMeta({
middleware: ["auth"], middleware: ["auth"],
@ -67,7 +68,7 @@
<div class="flex justify-end mb-2"> <div class="flex justify-end mb-2">
<div class="btn-group"> <div class="btn-group">
<button class="btn btn-sm tooltip tooltip-top" data-tip="Collapse Tree" @click="closeAll"> <button class="btn btn-sm tooltip tooltip-top" data-tip="Collapse Tree" @click="closeAll">
<Icon name="mdi-collapse-all-outline" /> <MdiCollapseAllOutline />
</button> </button>
</div> </div>
</div> </div>

View file

@ -2,6 +2,12 @@
import { Detail } from "~~/components/global/DetailsSection/types"; import { Detail } from "~~/components/global/DetailsSection/types";
import { themes } from "~~/lib/data/themes"; import { themes } from "~~/lib/data/themes";
import { CurrenciesCurrency, NotifierCreate, NotifierOut } from "~~/lib/api/types/data-contracts"; import { CurrenciesCurrency, NotifierCreate, NotifierOut } from "~~/lib/api/types/data-contracts";
import MdiAccount from "~icons/mdi/account";
import MdiMegaphone from "~icons/mdi/megaphone";
import MdiDelete from "~icons/mdi/delete";
import MdiFill from "~icons/mdi/fill";
import MdiPencil from "~icons/mdi/pencil";
import MdiAccountMultiple from "~icons/mdi/account-multiple";
definePageMeta({ definePageMeta({
middleware: ["auth"], middleware: ["auth"],
@ -341,7 +347,7 @@
<BaseCard> <BaseCard>
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>
<Icon name="mdi-account" class="mr-2 -mt-1 text-base-600" /> <MdiAccount class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> User Profile </span> <span class="text-base-600"> User Profile </span>
<template #description> Invite users, and manage your account. </template> <template #description> Invite users, and manage your account. </template>
</BaseSectionHeader> </BaseSectionHeader>
@ -368,7 +374,7 @@
<BaseCard> <BaseCard>
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>
<Icon name="mdi-megaphone" class="mr-2 -mt-1 text-base-600" /> <MdiMegaphone class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> Notifiers </span> <span class="text-base-600"> Notifiers </span>
<template #description> Get notifications for up coming maintenance reminders </template> <template #description> Get notifications for up coming maintenance reminders </template>
</BaseSectionHeader> </BaseSectionHeader>
@ -381,12 +387,12 @@
<div class="flex gap-2 justify-end"> <div class="flex gap-2 justify-end">
<div class="tooltip" data-tip="Delete"> <div class="tooltip" data-tip="Delete">
<button class="btn btn-sm btn-square" @click="deleteNotifier(n.id)"> <button class="btn btn-sm btn-square" @click="deleteNotifier(n.id)">
<Icon name="mdi-delete" /> <MdiDelete />
</button> </button>
</div> </div>
<div class="tooltip" data-tip="Edit"> <div class="tooltip" data-tip="Edit">
<button class="btn btn-sm btn-square" @click="openNotifierDialog(n)"> <button class="btn btn-sm btn-square" @click="openNotifierDialog(n)">
<Icon name="mdi-pencil" /> <MdiPencil />
</button> </button>
</div> </div>
</div> </div>
@ -412,7 +418,7 @@
<BaseCard> <BaseCard>
<template #title> <template #title>
<BaseSectionHeader class="pb-0"> <BaseSectionHeader class="pb-0">
<Icon name="mdi-accounts" class="mr-2 -mt-1 text-base-600" /> <MdiAccountMultiple class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> Group Settings </span> <span class="text-base-600"> Group Settings </span>
<template #description> <template #description>
Shared Group Settings. You may need to refresh your browser for some settings to apply. Shared Group Settings. You may need to refresh your browser for some settings to apply.
@ -433,7 +439,7 @@
<BaseCard> <BaseCard>
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>
<Icon name="mdi-fill" class="mr-2 text-base-600" /> <MdiFill class="mr-2 text-base-600" />
<span class="text-base-600"> Theme Settings </span> <span class="text-base-600"> Theme Settings </span>
<template #description> <template #description>
Theme settings are stored in your browser's local storage. You can change the theme at any time. If you're Theme settings are stored in your browser's local storage. You can change the theme at any time. If you're
@ -484,7 +490,7 @@
<BaseCard> <BaseCard>
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>
<Icon name="mdi-delete" class="mr-2 -mt-1 text-base-600" /> <MdiDelete class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> Delete Account</span> <span class="text-base-600"> Delete Account</span>
<template #description> Delete your account and all its associated data. </template> <template #description> Delete your account and all its associated data. </template>
</BaseSectionHeader> </BaseSectionHeader>

View file

@ -5,7 +5,7 @@
<BaseCard> <BaseCard>
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>
<Icon name="mdi-file-chart" class="mr-2 -mt-1" /> <MdiFileChart class="mr-2" />
<span> Reports </span> <span> Reports </span>
<template #description> Generate different reports for your inventory. </template> <template #description> Generate different reports for your inventory. </template>
</BaseSectionHeader> </BaseSectionHeader>
@ -17,7 +17,7 @@
are able to print labels ahead of time and apply them to your inventory when you receive them. are able to print labels ahead of time and apply them to your inventory when you receive them.
<template #button> <template #button>
Label Generator Label Generator
<Icon name="mdi-arrow-right" class="ml-2" /> <MdiArrowRight class="ml-2" />
</template> </template>
</DetailAction> </DetailAction>
<DetailAction @action="getBillOfMaterials()"> <DetailAction @action="getBillOfMaterials()">
@ -31,7 +31,7 @@
<BaseCard> <BaseCard>
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>
<Icon name="mdi-database" class="mr-2 -mt-1" /> <MdiDatabase class="mr-2" />
<span> Import / Export </span> <span> Import / Export </span>
<template #description> <template #description>
Import and export your inventory to and from a CSV file. This is useful for migrating your inventory to a Import and export your inventory to and from a CSV file. This is useful for migrating your inventory to a
@ -54,7 +54,7 @@
<BaseCard> <BaseCard>
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>
<Icon name="mdi-warning" class="mr-2 -mt-1" /> <MdiAlert class="mr-2" />
<span> Inventory Actions </span> <span> Inventory Actions </span>
<template #description> <template #description>
Apply Actions to your inventory in bulk. These are irreversible actions. <b>Be careful.</b> Apply Actions to your inventory in bulk. These are irreversible actions. <b>Be careful.</b>
@ -95,6 +95,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import MdiFileChart from "~icons/mdi/file-chart";
import MdiArrowRight from "~icons/mdi/arrow-right";
import MdiDatabase from "~icons/mdi/database";
import MdiAlert from "~icons/mdi/alert";
definePageMeta({ definePageMeta({
middleware: ["auth"], middleware: ["auth"],
}); });

View file

@ -8,9 +8,6 @@ dependencies:
'@headlessui/vue': '@headlessui/vue':
specifier: ^1.7.9 specifier: ^1.7.9
version: 1.7.9(vue@3.3.4) version: 1.7.9(vue@3.3.4)
'@iconify/vue':
specifier: ^3.2.1
version: 3.2.1(vue@3.3.4)
'@nuxtjs/tailwindcss': '@nuxtjs/tailwindcss':
specifier: ^6.1.3 specifier: ^6.1.3
version: 6.1.3(rollup@2.79.1)(webpack@5.90.3) version: 6.1.3(rollup@2.79.1)(webpack@5.90.3)
@ -82,6 +79,9 @@ devDependencies:
'@faker-js/faker': '@faker-js/faker':
specifier: ^8.0.0 specifier: ^8.0.0
version: 8.0.0 version: 8.0.0
'@iconify-json/mdi':
specifier: ^1.1.64
version: 1.1.64
'@nuxtjs/eslint-config-typescript': '@nuxtjs/eslint-config-typescript':
specifier: ^12.0.0 specifier: ^12.0.0
version: 12.0.0(eslint@8.29.0)(typescript@5.0.2) version: 12.0.0(eslint@8.29.0)(typescript@5.0.2)
@ -124,6 +124,9 @@ devDependencies:
typescript: typescript:
specifier: ^5.0.0 specifier: ^5.0.0
version: 5.0.2 version: 5.0.2
unplugin-icons:
specifier: ^0.18.5
version: 0.18.5
vite-plugin-eslint: vite-plugin-eslint:
specifier: ^1.8.1 specifier: ^1.8.1
version: 1.8.1(eslint@8.29.0)(vite@5.1.4) version: 1.8.1(eslint@8.29.0)(vite@5.1.4)
@ -148,6 +151,23 @@ packages:
'@jridgewell/trace-mapping': 0.3.23 '@jridgewell/trace-mapping': 0.3.23
dev: true dev: true
/@antfu/install-pkg@0.1.1:
resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==}
dependencies:
execa: 5.1.1
find-up: 5.0.0
dev: true
/@antfu/install-pkg@0.3.1:
resolution: {integrity: sha512-A3zWY9VeTPnxlMiZtsGHw2lSd3ghwvL8s9RiGOtqvDxhhFfZ781ynsGBa/iUnDJ5zBrmTFQrJDud3TGgRISaxw==}
dependencies:
execa: 8.0.1
dev: true
/@antfu/utils@0.7.7:
resolution: {integrity: sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg==}
dev: true
/@apideck/better-ajv-errors@0.3.6(ajv@8.12.0): /@apideck/better-ajv-errors@0.3.6(ajv@8.12.0):
resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==} resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -2440,13 +2460,29 @@ packages:
/@humanwhocodes/object-schema@1.2.1: /@humanwhocodes/object-schema@1.2.1:
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
/@iconify/vue@3.2.1(vue@3.3.4): /@iconify-json/mdi@1.1.64:
resolution: {integrity: sha512-c4R6ZgFo1JrJ8aPMMgOPgfU7lBswihMGR+yWe/P4ZukC3kTkeT4+lkt9Pc/itVFMkwva/S/7u9YofmYv57fnNQ==} resolution: {integrity: sha512-zGeo5TjhNFAY6FmSDBLAzDO811t77r6v/mDi7CAL9w5eXqKez6bIjk8R9AL/RHIeq44ALP4Ozr4lMqFTkHr7ug==}
peerDependencies:
vue: 3.x
dependencies: dependencies:
vue: 3.3.4 '@iconify/types': 2.0.0
dev: false dev: true
/@iconify/types@2.0.0:
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
dev: true
/@iconify/utils@2.1.22:
resolution: {integrity: sha512-6UHVzTVXmvO8uS6xFF+L/QTSpTzA/JZxtgU+KYGFyDYMEObZ1bu/b5l+zNJjHy+0leWjHI+C0pXlzGvv3oXZMA==}
dependencies:
'@antfu/install-pkg': 0.1.1
'@antfu/utils': 0.7.7
'@iconify/types': 2.0.0
debug: 4.3.4
kolorist: 1.8.0
local-pkg: 0.5.0
mlly: 1.6.1
transitivePeerDependencies:
- supports-color
dev: true
/@ioredis/commands@1.2.0: /@ioredis/commands@1.2.0:
resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==}
@ -4389,7 +4425,7 @@ packages:
engines: {node: '>= 6'} engines: {node: '>= 6'}
dependencies: dependencies:
glob: 7.2.3 glob: 7.2.3
graceful-fs: 4.2.10 graceful-fs: 4.2.11
lazystream: 1.0.1 lazystream: 1.0.1
lodash.defaults: 4.2.0 lodash.defaults: 4.2.0
lodash.difference: 4.5.0 lodash.difference: 4.5.0
@ -5548,7 +5584,7 @@ packages:
resolution: {integrity: sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==} resolution: {integrity: sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
graceful-fs: 4.2.10 graceful-fs: 4.2.11
memory-fs: 0.5.0 memory-fs: 0.5.0
tapable: 1.1.3 tapable: 1.1.3
@ -5564,7 +5600,7 @@ packages:
resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==} resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==}
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
dependencies: dependencies:
graceful-fs: 4.2.10 graceful-fs: 4.2.11
tapable: 2.2.1 tapable: 2.2.1
/enhanced-resolve@5.15.1: /enhanced-resolve@5.15.1:
@ -6794,7 +6830,6 @@ packages:
/graceful-fs@4.2.11: /graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
dev: false
/grapheme-splitter@1.0.4: /grapheme-splitter@1.0.4:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
@ -7435,7 +7470,7 @@ packages:
dependencies: dependencies:
universalify: 2.0.0 universalify: 2.0.0
optionalDependencies: optionalDependencies:
graceful-fs: 4.2.10 graceful-fs: 4.2.11
/jsonpointer@5.0.1: /jsonpointer@5.0.1:
resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==}
@ -7524,6 +7559,10 @@ packages:
- supports-color - supports-color
dev: false dev: false
/kolorist@1.8.0:
resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
dev: true
/lazystream@1.0.1: /lazystream@1.0.1:
resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
engines: {node: '>= 0.6.3'} engines: {node: '>= 0.6.3'}
@ -10567,6 +10606,37 @@ packages:
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
/unplugin-icons@0.18.5:
resolution: {integrity: sha512-KVNAohXbZ7tVcG1C3p6QaC7wU9Qrj7etv4XvsMMJAxr5LccQZ+Iuv5LOIv/7GtqXaGN1BuFCqRO1ErsHEgEXdQ==}
peerDependencies:
'@svgr/core': '>=7.0.0'
'@svgx/core': ^1.0.1
'@vue/compiler-sfc': ^3.0.2 || ^2.7.0
vue-template-compiler: ^2.6.12
vue-template-es2015-compiler: ^1.9.0
peerDependenciesMeta:
'@svgr/core':
optional: true
'@svgx/core':
optional: true
'@vue/compiler-sfc':
optional: true
vue-template-compiler:
optional: true
vue-template-es2015-compiler:
optional: true
dependencies:
'@antfu/install-pkg': 0.3.1
'@antfu/utils': 0.7.7
'@iconify/utils': 2.1.22
debug: 4.3.4
kolorist: 1.8.0
local-pkg: 0.5.0
unplugin: 1.7.1
transitivePeerDependencies:
- supports-color
dev: true
/unplugin-vue-router@0.6.4(rollup@2.79.1)(vue-router@4.2.4)(vue@3.3.4): /unplugin-vue-router@0.6.4(rollup@2.79.1)(vue-router@4.2.4)(vue@3.3.4):
resolution: {integrity: sha512-9THVhhtbVFxbsIibjK59oPwMI1UCxRWRPX7azSkTUABsxovlOXJys5SJx0kd/0oKIqNJuYgkRfAgPuO77SqCOg==} resolution: {integrity: sha512-9THVhhtbVFxbsIibjK59oPwMI1UCxRWRPX7azSkTUABsxovlOXJys5SJx0kd/0oKIqNJuYgkRfAgPuO77SqCOg==}
peerDependencies: peerDependencies:
@ -11383,7 +11453,6 @@ packages:
/workbox-google-analytics@7.0.0: /workbox-google-analytics@7.0.0:
resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==} resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==}
deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained
dependencies: dependencies:
workbox-background-sync: 7.0.0 workbox-background-sync: 7.0.0
workbox-core: 7.0.0 workbox-core: 7.0.0