zwischenstand

This commit is contained in:
Martin Drechsel
2025-05-06 11:09:56 +02:00
parent 410a885d21
commit b729c8ebbe
40 changed files with 2252 additions and 376 deletions

View File

@ -0,0 +1,102 @@
<template>
<UiDialog :title="t('title')" v-model:open="open">
<div>
<i18n-t keypath="question" tag="p">
<template #extension>
<span class="font-bold text-primary">{{ manifest?.name }}</span>
</template>
</i18n-t>
<!-- {{ t("question", { extension: manifest?.name }) }}
<span class="font-bold text-primary">{{ manifest?.name }}</span> zu HaexHub hinzufügen? -->
</div>
<div class="flex flex-col">
<HaexExtensionManifestPermissionsFilesystem
v-if="manifest?.permissions?.filesystem"
:filesystem="manifest?.permissions?.filesystem"
/>
<HaexExtensionManifestPermissionsDatabase
v-if="manifest?.permissions?.database"
:database="manifest?.permissions?.database"
/>
<HaexExtensionManifestPermissionsHttp
v-if="manifest?.permissions?.http"
:http="manifest?.permissions?.http"
/>
<!-- <VaultCard>
<template #header>
<h3>{{ t("filesystem.title") }}</h3>
</template>
<div>
{{ manifest?.permissions.filesystem }}
</div>
</VaultCard>
<VaultCard>
<template #header>
<h3>{{ t("http.title") }}</h3>
</template>
<div>
{{ manifest?.permissions.http }}
</div>
</VaultCard> -->
</div>
<template #buttons>
<UiButton @click="onDeny" class="btn-error btn-outline">{{ t("deny") }} </UiButton>
<UiButton @click="onConfirm" class="btn-success btn-outline">{{ t("confirm") }}</UiButton>
</template>
</UiDialog>
</template>
<script setup lang="ts">
const { t } = useI18n();
const open = defineModel<boolean>("open", { default: false });
defineProps<{ manifest?: IHaexHubExtensionManifest }>();
const emit = defineEmits(["deny", "confirm"]);
const onDeny = () => {
open.value = false;
console.log("onDeny open", open.value);
emit("deny");
};
const onConfirm = () => {
open.value = false;
console.log("onConfirm open", open.value);
emit("confirm");
};
</script>
<i18n lang="json">
{
"de": {
"title": "Erweiterung hinzufügen",
"question": "Möchtest du die Erweiterung {extension} hinzufügen?",
"confirm": "Bestätigen",
"deny": "Ablehnen",
"permission": {
"read": "Lesen",
"write": "Schreiben"
},
"database": {
"title": "Datenbank Berechtigungen"
},
"http": {
"title": "Internet Berechtigungen"
},
"filesystem": {
"title": "Dateisystem Berechtigungen"
}
},
"en": { "title": "Confirm Permission" }
}
</i18n>

View File

@ -0,0 +1,63 @@
<template>
<div>
<HaexExtensionManifestPermissionsTitle>
{{ t("database.title") }}
</HaexExtensionManifestPermissionsTitle>
<div v-if="database?.read?.length">
<UiAccordion>
<template #title>
<h3>{{ t("permission.read") }}</h3>
</template>
<ul class="space-y-0.5">
<li class="flex items-center justify-between px-4 py-0.5" v-for="read in database?.read">
<div class="flex items-center gap-2">
<span>{{ read }}</span>
</div>
</li>
</ul>
</UiAccordion>
</div>
<div v-if="database?.write?.length">
<UiAccordion>
<template #title>
<h3>{{ t("permission.write") }}</h3>
</template>
<ul class="space-y-0.5">
<li
class="flex items-center justify-between px-4 py-0.5"
v-for="write in database?.write"
>
<div class="flex items-center gap-2">
<span>{{ write }}</span>
</div>
</li>
</ul>
</UiAccordion>
</div>
</div>
</template>
<script setup lang="ts">
defineProps<{ database: IHaexHubExtensionManifest["permissions"]["database"] }>();
const { t } = useI18n();
</script>
<i18n lang="json">
{
"de": {
"permission": {
"read": "Lesen",
"write": "Schreiben"
},
"database": {
"title": "Datenbank Berechtigungen"
}
},
"en": { "title": "Confirm Permission" }
}
</i18n>

View File

@ -0,0 +1,65 @@
<template>
<div>
<HaexExtensionManifestPermissionsTitle>
{{ t("filesystem.title") }}
</HaexExtensionManifestPermissionsTitle>
<div v-if="filesystem?.read?.length">
<UiAccordion>
<template #title>
<h3>{{ t("permission.read") }}</h3>
</template>
<ul class="space-y-0.5">
<li
class="flex items-center justify-between px-4 py-0.5"
v-for="read in filesystem?.read"
>
<div class="flex items-center gap-2">
<span>{{ read }}</span>
</div>
</li>
</ul>
</UiAccordion>
</div>
<div v-if="filesystem?.write?.length">
<UiAccordion>
<template #title>
<h3>{{ t("permission.write") }}</h3>
</template>
<ul class="space-y-0.5">
<li
class="flex items-center justify-between px-4 py-0.5"
v-for="write in filesystem?.write"
>
<div class="flex items-center gap-2">
<span>{{ write }}</span>
</div>
</li>
</ul>
</UiAccordion>
</div>
</div>
</template>
<script setup lang="ts">
defineProps<{ filesystem: IHaexHubExtensionManifest["permissions"]["filesystem"] }>();
const { t } = useI18n();
</script>
<i18n lang="json">
{
"de": {
"permission": {
"read": "Lesen",
"write": "Schreiben"
},
"filesystem": {
"title": "Dateisystem Berechtigungen"
}
},
"en": { "title": "Confirm Permission" }
}
</i18n>

View File

@ -0,0 +1,43 @@
<template>
<div>
<HaexExtensionManifestPermissionsTitle>
{{ t("http.title") }}
</HaexExtensionManifestPermissionsTitle>
<div v-if="http?.length">
<UiAccordion>
<template #title>
<h3>{{ t("permission.access") }}</h3>
</template>
<ul class="space-y-0.5">
<li class="flex items-center justify-between px-4 py-0.5" v-for="access in http">
<div class="flex items-center gap-2">
<span>{{ access }}</span>
</div>
</li>
</ul>
</UiAccordion>
</div>
</div>
</template>
<script setup lang="ts">
defineProps<{ http: IHaexHubExtensionManifest["permissions"]["http"] }>();
const { t } = useI18n();
</script>
<i18n lang="json">
{
"de": {
"permission": {
"access": "Zugriff"
},
"http": {
"title": "Internet Berechtigungen"
}
},
"en": { "title": "Confirm Permission" }
}
</i18n>

View File

@ -0,0 +1,5 @@
<template>
<div class="text-base-content/50 px-4 py-2 text-md font-medium">
<slot />
</div>
</template>

View File

@ -0,0 +1,43 @@
<template>
<div class="accordion divide-neutral/20 divide-y">
<div class="accordion-item active" :id="itemId" ref="accordionRef">
<button
class="accordion-toggle inline-flex items-center gap-x-4 text-start"
:aria-controls="collapseId"
aria-expanded="true"
type="button"
>
<span
class="icon-[tabler--chevron-right] accordion-item-active:rotate-90 size-5 shrink-0 transition-transform duration-300 rtl:rotate-180"
></span>
<slot name="title" />
</button>
<div
:id="collapseId"
class="accordion-content w-full overflow-hidden transition-[height] duration-300"
:aria-labelledby="itemId"
role="region"
>
<div class="px-5 pb-4">
<slot />
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { HSAccordion } from "flyonui/flyonui";
const itemId = useId();
const collapseId = useId();
const accordionRef = useTemplateRef("accordionRef");
const accordion = ref<HSAccordion>();
onMounted(() => {
if (accordionRef.value) {
accordion.value = new HSAccordion(accordionRef.value);
}
});
</script>

View File

@ -1,9 +1,5 @@
<template>
<slot
name="trigger"
:id
>
</slot>
<slot name="trigger" :id> </slot>
<div
:id
@ -17,10 +13,7 @@
<div class="modal-content">
<div class="modal-header">
<slot name="title">
<h3
v-if="title"
class="modal-title text-base sm:text-lg"
>
<h3 v-if="title" class="modal-title text-base sm:text-lg">
{{ title }}
</h3>
</slot>
@ -32,10 +25,7 @@
@click="open = false"
tabindex="1"
>
<Icon
name="mdi:close"
size="18"
/>
<Icon name="mdi:close" size="18" />
</button>
</div>
<div class="modal-body text-sm sm:text-base py-1">
@ -50,7 +40,7 @@
</template>
<script setup lang="ts">
import { HSOverlay } from 'flyonui/flyonui';
import { HSOverlay } from "flyonui/flyonui";
export interface IDom {
class?: String;
@ -63,38 +53,39 @@ defineProps({
trigger: {
type: Object as PropType<IDom>,
default: () => ({
class: '',
text: '',
class: "",
text: "",
}),
},
title: {
type: String,
default: '',
default: "",
},
description: {
type: Object as PropType<IDom>,
default: () => ({
class: '',
text: '',
class: "",
text: "",
}),
required: false,
},
});
const open = defineModel<boolean>('open', { default: false });
const open = defineModel<boolean>("open", { default: false });
const { t } = useI18n();
const modalRef = useTemplateRef('modalRef');
const modalRef = useTemplateRef("modalRef");
const modal = ref<HSOverlay>();
watch(open, async () => {
console.log("open modal", open.value);
if (open.value) {
//console.log('open modal', modal.value?.open);
await modal.value?.open();
} else {
await modal.value?.close(true);
const res = await modal.value?.close(true);
console.log("close dialog", res);
}
});
@ -102,8 +93,8 @@ onMounted(() => {
if (!modalRef.value) return;
modal.value = new HSOverlay(modalRef.value, { isClosePrev: true });
modal.value.on('close', () => {
console.log('close it from event', open.value);
modal.value.on("close", () => {
console.log("close it from event", open.value);
open.value = false;
});
});

View File

@ -0,0 +1,49 @@
<template>
<li
@click="triggerNavigate"
class="hover:text-primary rounded"
:class="{ ['bg-base-300']: isActive }"
>
<UiTooltip :tooltip="tooltip ?? name" direction="right-start">
<NuxtLinkLocale
:to="{ name: 'haexExtension', params: { extensionId: props.id } }"
class="flex items-center justify-center cursor-pointer tooltip-toogle"
ref="link"
>
<div v-html="icon" class="shrink-0 size-6" />
<!-- <Icon mode="svg" :name="icon" class="shrink-0 size-6" /> -->
</NuxtLinkLocale>
</UiTooltip>
</li>
</template>
<script setup lang="ts">
import { type ISidebarItem } from "#imports";
const props = defineProps<ISidebarItem>();
console.log("image", props.icon);
const router = useRouter();
const isActive = computed(() => {
if (props.to?.name === "haexExtension") {
return getSingleRouteParam(router.currentRoute.value.params.extensionId) === props.id;
} else {
return props.to?.name === router.currentRoute.value.meta.name;
}
});
const link = useTemplateRef("link");
const triggerNavigate = () => link.value?.$el.click();
/* computed(() => {
const found = useRouter()
.getRoutes()
.find((route) => route.name === useLocaleRoute()(props.to)?.name);
console.log('found route', found, useRoute());
return (
found?.name === useRoute().name ||
found?.children.some((child) => child.name === useRoute().name)
);
}); */
</script>

View File

@ -71,7 +71,8 @@ const { add } = useSnackbar();
const handleError = (error: unknown) => {
isOpen.value = false;
add({ type: "error", text: JSON.stringify(error) });
console.log("handleError", error, typeof error);
add({ type: "error", text: "Passwort falsch" });
//console.error(error);
};
@ -100,6 +101,7 @@ const onLoadDatabase = async () => {
};
const localePath = useLocalePath();
const onOpenDatabase = async () => {
try {
check.value = true;
@ -120,7 +122,10 @@ const onOpenDatabase = async () => {
});
if (!vaultId) {
add({ type: "error", text: "Vault konnte nicht geöffnet werden" });
add({
type: "error",
text: "Vault konnte nicht geöffnet werden. \n Vermutlich ist das Passwort falsch",
});
return;
}

View File

@ -1,14 +1,27 @@
<template>
<div
class="bg-base-100 w-full mx-auto shadow h-full overflow-hidden pt-[7.5rem]"
>
<div class="card">
<slot name="image" />
<div class="card-header">
<h5 class="card-title" v-if="$slots.title">
<slot name="title" />
</h5>
</div>
<div class="card-body">
<slot />
<div class="card-actions" v-if="$slots.action">
<slot name="action" />
</div>
</div>
</div>
<!-- <div class="bg-base-100 w-full mx-auto shadow h-full overflow-hidden pt-[7.5rem]">
<div
class="fixed top-0 right-0 z-10 transition-all duration-700 w-full font-semibold text-lg h-[7.5rem]"
:class="{ 'pl-96': show }"
>
<div
class="justify-center items-center flex flex-wrap border-b rounded-b border-secondary h-full"
:class="{ 'pl-12': !show }"
>
<slot name="header" />
</div>
@ -17,26 +30,25 @@
<div class="h-full overflow-scroll bg-base-200">
<slot />
</div>
</div>
</div> -->
</template>
<script setup lang="ts">
const { show } = storeToRefs(useSidebarStore());
const emit = defineEmits(['close', 'submit']);
const emit = defineEmits(["close", "submit"]);
const { escape, enter } = useMagicKeys();
watchEffect(async () => {
if (escape.value) {
await nextTick();
emit('close');
emit("close");
}
});
watchEffect(async () => {
if (enter.value) {
await nextTick();
emit('submit');
emit("submit");
}
});
</script>