UNPKG

@nextcloud/vue

Version:
826 lines (825 loc) 33.4 kB
import '../assets/NcProfileHoverCard.css'; import { openBlock, createElementBlock, mergeProps, createElementVNode, toDisplayString, createCommentVNode, defineComponent, ref, computed, watch, onMounted, unref, normalizeClass, createVNode, Fragment, createBlock, withCtx, resolveDynamicComponent, createSlots, createTextVNode, renderList } from "vue"; import { getCurrentUser } from "@nextcloud/auth"; import axios from "@nextcloud/axios"; import { getCapabilities } from "@nextcloud/capabilities"; import { getCanonicalLocale } from "@nextcloud/l10n"; import { generateUrl, generateOcsUrl } from "@nextcloud/router"; import { _ as _export_sfc } from "./_plugin-vue_export-helper.mjs"; import { N as NcActionButton } from "./NcActionButton.mjs"; import { N as NcActionLink } from "./NcActionLink.mjs"; import { N as NcActionRouter } from "./NcActionRouter.mjs"; import { N as NcActions } from "./NcActions.mjs"; import { N as NcAvatar } from "./NcAvatar.mjs"; import { N as NcButton } from "./NcButton.mjs"; import { N as NcLoadingIcon } from "./NcLoadingIcon.mjs"; import { N as NcRichText } from "./NcRichText.mjs"; import { useIsSmallMobile } from "../composables/useIsMobile/index.mjs"; import { r as register, R as t25, a as t } from "./_l10n.mjs"; import { l as logger } from "./logger.mjs"; import { N as NcIconSvgWrapper } from "./NcIconSvgWrapper.mjs"; const _sfc_main$4 = { name: "BriefcaseOutlineIcon", emits: ["click"], props: { title: { type: String }, fillColor: { type: String, default: "currentColor" }, size: { type: Number, default: 24 } } }; const _hoisted_1$4 = ["aria-hidden", "aria-label"]; const _hoisted_2$4 = ["fill", "width", "height"]; const _hoisted_3$4 = { d: "M20,6C20.58,6 21.05,6.2 21.42,6.59C21.8,7 22,7.45 22,8V19C22,19.55 21.8,20 21.42,20.41C21.05,20.8 20.58,21 20,21H4C3.42,21 2.95,20.8 2.58,20.41C2.2,20 2,19.55 2,19V8C2,7.45 2.2,7 2.58,6.59C2.95,6.2 3.42,6 4,6H8V4C8,3.42 8.2,2.95 8.58,2.58C8.95,2.2 9.42,2 10,2H14C14.58,2 15.05,2.2 15.42,2.58C15.8,2.95 16,3.42 16,4V6H20M4,8V19H20V8H4M14,6V4H10V6H14Z" }; const _hoisted_4$4 = { key: 0 }; function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) { return openBlock(), createElementBlock("span", mergeProps(_ctx.$attrs, { "aria-hidden": $props.title ? null : "true", "aria-label": $props.title, class: "material-design-icon briefcase-outline-icon", role: "img", onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("click", $event)) }), [ (openBlock(), createElementBlock("svg", { fill: $props.fillColor, class: "material-design-icon__svg", width: $props.size, height: $props.size, viewBox: "0 0 24 24" }, [ createElementVNode("path", _hoisted_3$4, [ $props.title ? (openBlock(), createElementBlock("title", _hoisted_4$4, toDisplayString($props.title), 1)) : createCommentVNode("", true) ]) ], 8, _hoisted_2$4)) ], 16, _hoisted_1$4); } const BriefcaseIcon = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$3]]); const _sfc_main$3 = { name: "ClockOutlineIcon", emits: ["click"], props: { title: { type: String }, fillColor: { type: String, default: "currentColor" }, size: { type: Number, default: 24 } } }; const _hoisted_1$3 = ["aria-hidden", "aria-label"]; const _hoisted_2$3 = ["fill", "width", "height"]; const _hoisted_3$3 = { d: "M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C6.47,22 2,17.5 2,12A10,10 0 0,1 12,2M12.5,7V12.25L17,14.92L16.25,16.15L11,13V7H12.5Z" }; const _hoisted_4$3 = { key: 0 }; function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) { return openBlock(), createElementBlock("span", mergeProps(_ctx.$attrs, { "aria-hidden": $props.title ? null : "true", "aria-label": $props.title, class: "material-design-icon clock-outline-icon", role: "img", onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("click", $event)) }), [ (openBlock(), createElementBlock("svg", { fill: $props.fillColor, class: "material-design-icon__svg", width: $props.size, height: $props.size, viewBox: "0 0 24 24" }, [ createElementVNode("path", _hoisted_3$3, [ $props.title ? (openBlock(), createElementBlock("title", _hoisted_4$3, toDisplayString($props.title), 1)) : createCommentVNode("", true) ]) ], 8, _hoisted_2$3)) ], 16, _hoisted_1$3); } const ClockIcon = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$2]]); const _sfc_main$2 = { name: "MapMarkerOutlineIcon", emits: ["click"], props: { title: { type: String }, fillColor: { type: String, default: "currentColor" }, size: { type: Number, default: 24 } } }; const _hoisted_1$2 = ["aria-hidden", "aria-label"]; const _hoisted_2$2 = ["fill", "width", "height"]; const _hoisted_3$2 = { d: "M12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5M12,2A7,7 0 0,1 19,9C19,14.25 12,22 12,22C12,22 5,14.25 5,9A7,7 0 0,1 12,2M12,4A5,5 0 0,0 7,9C7,10 7,12 12,18.71C17,12 17,10 17,9A5,5 0 0,0 12,4Z" }; const _hoisted_4$2 = { key: 0 }; function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) { return openBlock(), createElementBlock("span", mergeProps(_ctx.$attrs, { "aria-hidden": $props.title ? null : "true", "aria-label": $props.title, class: "material-design-icon map-marker-outline-icon", role: "img", onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("click", $event)) }), [ (openBlock(), createElementBlock("svg", { fill: $props.fillColor, class: "material-design-icon__svg", width: $props.size, height: $props.size, viewBox: "0 0 24 24" }, [ createElementVNode("path", _hoisted_3$2, [ $props.title ? (openBlock(), createElementBlock("title", _hoisted_4$2, toDisplayString($props.title), 1)) : createCommentVNode("", true) ]) ], 8, _hoisted_2$2)) ], 16, _hoisted_1$2); } const MapMarkerIcon = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$1]]); const _sfc_main$1 = { name: "PencilOutlineIcon", emits: ["click"], props: { title: { type: String }, fillColor: { type: String, default: "currentColor" }, size: { type: Number, default: 24 } } }; const _hoisted_1$1 = ["aria-hidden", "aria-label"]; const _hoisted_2$1 = ["fill", "width", "height"]; const _hoisted_3$1 = { d: "M14.06,9L15,9.94L5.92,19H5V18.08L14.06,9M17.66,3C17.41,3 17.15,3.1 16.96,3.29L15.13,5.12L18.88,8.87L20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18.17,3.09 17.92,3 17.66,3M14.06,6.19L3,17.25V21H6.75L17.81,9.94L14.06,6.19Z" }; const _hoisted_4$1 = { key: 0 }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { return openBlock(), createElementBlock("span", mergeProps(_ctx.$attrs, { "aria-hidden": $props.title ? null : "true", "aria-label": $props.title, class: "material-design-icon pencil-outline-icon", role: "img", onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("click", $event)) }), [ (openBlock(), createElementBlock("svg", { fill: $props.fillColor, class: "material-design-icon__svg", width: $props.size, height: $props.size, viewBox: "0 0 24 24" }, [ createElementVNode("path", _hoisted_3$1, [ $props.title ? (openBlock(), createElementBlock("title", _hoisted_4$1, toDisplayString($props.title), 1)) : createCommentVNode("", true) ]) ], 8, _hoisted_2$1)) ], 16, _hoisted_1$1); } const PencilIcon = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render]]); register(t25); /*! * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ const PROFILE_CACHE_TTL_MS = 30 * 60 * 1e3; const cache = /* @__PURE__ */ new Map(); const inflight = /* @__PURE__ */ new Map(); function getCachedProfile(userId) { const entry = cache.get(userId); if (!entry) { return null; } if (Date.now() >= entry.expiresAt) { cache.delete(userId); return null; } return entry.data; } function setCachedProfile(userId, data, ttlMs = PROFILE_CACHE_TTL_MS) { cache.set(userId, { data, expiresAt: Date.now() + ttlMs }); } async function fetchProfileCached(userId, fetcher, ttlMs = PROFILE_CACHE_TTL_MS) { const cached = getCachedProfile(userId); if (cached) { return cached; } const pending = inflight.get(userId); if (pending) { return pending; } const promise = (async () => { try { const data = await fetcher(); if (data) { setCachedProfile(userId, data, ttlMs); } return data; } finally { inflight.delete(userId); } })(); inflight.set(userId, promise); return promise; } const _hoisted_1 = ["aria-label"]; const _hoisted_2 = { key: 0, class: "profile-hover-card__loading" }; const _hoisted_3 = { class: "profile-hover-card__header" }; const _hoisted_4 = { class: "profile-hover-card__header__container" }; const _hoisted_5 = { key: 1, class: "profile-hover-card__header__container__placeholder" }; const _hoisted_6 = { class: "profile-hover-card__header__container__identity" }; const _hoisted_7 = { class: "profile-hover-card__header__container__displayname" }; const _hoisted_8 = ["href"]; const _hoisted_9 = { key: 1 }; const _hoisted_10 = { key: 2, class: "profile-hover-card__header__container__pronoun-separator" }; const _hoisted_11 = { key: 3, class: "profile-hover-card__header__container__pronouns" }; const _hoisted_12 = { key: 0, class: "profile-hover-card__header__container__status" }; const _hoisted_13 = { class: "profile-hover-card__header__container__status-content" }; const _hoisted_14 = { class: "profile-hover-card__body" }; const _hoisted_15 = { class: "profile-hover-card__content" }; const _hoisted_16 = { class: "profile-hover-card__sidebar" }; const _hoisted_17 = { class: "user-actions" }; const _hoisted_18 = { key: 0, class: "user-actions__loading" }; const _hoisted_19 = ["src"]; const _hoisted_20 = ["src"]; const _hoisted_21 = { key: 0, class: "profile-hover-card__blocks" }; const _hoisted_22 = { key: 0, class: "profile-hover-card__blocks-details" }; const _hoisted_23 = { key: 0, class: "detail" }; const _hoisted_24 = { key: 0 }; const _hoisted_25 = { key: 1, class: "detail" }; const _hoisted_26 = { key: 2, class: "detail" }; const _hoisted_27 = { key: 0, class: "profile-hover-card__blocks-headline" }; const _hoisted_28 = { key: 1, class: "profile-hover-card__blocks-biography" }; const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "NcProfileHoverCard", props: { user: { default: null }, displayName: { default: null }, profile: { default: null }, preloadedUserStatus: { default: null }, open: { type: Boolean, default: false }, actions: { default: null }, actionsLoading: { type: Boolean, default: false } }, setup(__props) { const props = __props; const loading = ref(false); const error = ref(false); const profileData = ref(props.profile); const userStatus = ref(props.preloadedUserStatus ?? {}); const profileEnabled = ref(!!props.profile); const userStatusReady = ref(props.preloadedUserStatus !== null); const isMobile = useIsSmallMobile(); const showLoading = computed(() => loading.value || !!profileData.value && !error.value && !userStatusReady.value); if (props.user && props.profile) { setCachedProfile(props.user, props.profile); } const isCurrentUser = computed(() => !!props.user && getCurrentUser()?.uid === props.user); const settingsUrl = generateUrl("/settings/user"); const profileUrl = computed(() => { if (!profileEnabled.value) { return null; } const userId = profileData.value?.userId || props.user; if (!userId) { return null; } return generateUrl("/u/{userId}", { userId }); }); const resolvedDisplayName = computed(() => profileData.value?.displayname || props.displayName || profileData.value?.userId || props.user || ""); const profileLinkProps = computed(() => { if (!profileUrl.value) { return {}; } return { href: profileUrl.value, "aria-label": t("View profile") }; }); function isSidebarAction(action) { return action.appId !== "timezone" && action.appId !== "profile" && action.id !== "profile"; } function actionDisplayText(action) { if (isCurrentUser.value) { return action.text; } if (action.id === "talk-call" || isSpreedDirectCallAction(action)) { return t("Start call"); } if (action.id === "talk" || action.appId === "spreed") { return t("Send message"); } return action.text; } function isSpreedDirectCallAction(action) { if (action.appId !== "spreed") { return false; } const href = action.href ?? (typeof action.to === "string" ? action.to : ""); return typeof href === "string" && href.includes("#direct-call"); } const resolvedActions = computed(() => { if (props.actions && props.actions.length > 0) { return props.actions.filter(isSidebarAction); } return (profileData.value?.actions ?? []).filter(isSidebarAction).map((action) => ({ id: action.id, appId: action.appId, text: action.title, href: action.target || void 0, icon: action.icon, target: action.id === "phone" ? "_self" : "_blank", rel: action.id === "fediverse" ? "me" : void 0 })); }); const localTimeLabel = computed(() => { const time = formatProfileLocalTime(/* @__PURE__ */ new Date()); if (!time) { return null; } return t("Local time: {time}", { time }); }); const primaryAction = computed(() => resolvedActions.value[0]); const otherActions = computed(() => resolvedActions.value.slice(1)); const primaryActionButtonProps = computed(() => { const action = primaryAction.value; if (!action) { return {}; } if (action.to) { return { to: action.to }; } if (action.href) { return { href: action.href, target: action.target ?? (action.href.startsWith("tel:") ? "_self" : "_blank"), rel: action.rel }; } return {}; }); const avatarUserStatus = computed(() => ({ status: userStatus.value.status ?? null, icon: userStatus.value.icon ?? null, message: userStatus.value.message ?? null })); function formatProfileLocalTime(date) { const timeZone = profileData.value?.timezone; if (timeZone) { try { return new Intl.DateTimeFormat(getCanonicalLocale(), { timeZone, hour: "2-digit", minute: "2-digit" }).format(date); } catch { } } if (typeof profileData.value?.timezoneOffset === "number") { const shifted = new Date(date.getTime() + profileData.value.timezoneOffset * 1e3); return new Intl.DateTimeFormat(getCanonicalLocale(), { timeZone: "UTC", hour: "2-digit", minute: "2-digit" }).format(shifted); } return null; } function isIconUrl(icon) { return !!icon && (/^(https?:)?\/\//.test(icon) || icon.startsWith("/") || icon.startsWith("data:")); } function otherActionComponent(action) { if (action.to) { return NcActionRouter; } if (action.onClick && !action.href) { return NcActionButton; } return NcActionLink; } function otherActionProps(action) { if (action.to) { return { to: action.to, closeAfterClick: true }; } if (action.onClick && !action.href) { return { onClick: action.onClick, closeAfterClick: true }; } return { href: action.href, target: action.target ?? (action.href?.startsWith("tel:") ? "_self" : "_blank"), rel: action.rel, closeAfterClick: true }; } watch(() => props.profile, (value) => { if (value) { profileData.value = value; profileEnabled.value = true; if (props.user) { setCachedProfile(props.user, value); } error.value = false; } }); watch(() => props.preloadedUserStatus, (value) => { if (value) { userStatus.value = value; userStatusReady.value = true; } }); watch(() => props.displayName, (value) => { if (value && profileData.value && !profileEnabled.value) { profileData.value = { ...profileData.value, displayname: value }; } }); watch(() => props.user, () => { profileData.value = props.profile; userStatus.value = props.preloadedUserStatus ?? {}; userStatusReady.value = props.preloadedUserStatus !== null; profileEnabled.value = !!props.profile; error.value = false; if (props.user && props.profile) { setCachedProfile(props.user, props.profile); } if (props.open) { loadProfile(); } }); watch(() => props.open, (isOpen) => { if (isOpen) { loadProfile(); } }); onMounted(() => { if (props.open) { loadProfile(); } }); async function resolveDisplayName(userId) { if (props.displayName) { return props.displayName; } try { const { data } = await axios.post(generateUrl("/displaynames"), { users: [userId] }); return data?.users?.[userId] || userId; } catch (e) { logger.debug("Failed to load display name for hovercard", { error: e, userId }); return userId; } } async function createLimitedProfile(userId) { return { userId, displayname: await resolveDisplayName(userId), actions: [], isUserAvatarVisible: true }; } async function ensureUserStatus(userId) { if (!userStatusReady.value) { userStatus.value = await fetchUserStatus(userId); userStatusReady.value = true; } } async function loadProfile() { if (!props.user || loading.value) { return; } const userId = props.user; if (!profileData.value) { const cached = getCachedProfile(userId); if (cached) { profileData.value = cached; profileEnabled.value = true; } } if (profileData.value && profileEnabled.value) { if (!userStatusReady.value) { loading.value = true; try { await ensureUserStatus(userId); } finally { loading.value = false; } } return; } loading.value = true; error.value = false; const statusPromise = userStatusReady.value ? Promise.resolve(userStatus.value) : fetchUserStatus(userId); try { const profile = await fetchProfileCached(userId, async () => { const { data } = await axios.get(generateOcsUrl("/profile/{userId}", { userId })); return data.ocs?.data ?? null; }); if (profile) { profileData.value = profile; profileEnabled.value = true; } else { profileData.value = await createLimitedProfile(userId); profileEnabled.value = false; } } catch (e) { logger.debug("Failed to load profile for hovercard, showing limited info", { error: e, user: userId }); profileData.value = await createLimitedProfile(userId); profileEnabled.value = false; } try { userStatus.value = await statusPromise; userStatusReady.value = true; } finally { loading.value = false; } } async function fetchUserStatus(userId) { try { if (!getCapabilities()?.user_status?.enabled || !getCurrentUser()) { return {}; } const { data } = await axios.get(generateOcsUrl("/apps/user_status/api/v1/statuses/{userId}", { userId })); return data.ocs?.data ?? {}; } catch (e) { logger.debug("Failed to load user status for hovercard", { error: e, userId }); return {}; } } return (_ctx, _cache) => { return openBlock(), createElementBlock("div", { class: normalizeClass(["profile-hover-card", { "profile-hover-card--limited": !showLoading.value && !!profileData.value && !error.value && !profileEnabled.value }]), role: "dialog", "aria-label": unref(t)("Profile of {user}", { user: resolvedDisplayName.value }) }, [ showLoading.value ? (openBlock(), createElementBlock("div", _hoisted_2, [ createVNode(NcLoadingIcon, { size: 32, name: unref(t)("Loading profile") }, null, 8, ["name"]) ])) : profileData.value && !error.value ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [ createElementVNode("div", _hoisted_3, [ isCurrentUser.value ? (openBlock(), createBlock(NcButton, { key: 0, class: "profile-hover-card__header__edit", variant: "tertiary", "aria-label": unref(t)("Edit profile"), title: unref(t)("Edit profile"), href: unref(settingsUrl), target: "_blank" }, { icon: withCtx(() => [ createVNode(PencilIcon, { size: 20 }) ]), _: 1 }, 8, ["aria-label", "title", "href"])) : createCommentVNode("", true), createElementVNode("div", _hoisted_4, [ unref(isMobile) ? (openBlock(), createBlock(resolveDynamicComponent(profileUrl.value ? "a" : "div"), mergeProps({ key: 0, class: ["profile-hover-card__header__container__avatar", { "profile-hover-card__profile-link": !!profileUrl.value }] }, profileLinkProps.value), { default: withCtx(() => [ createVNode(NcAvatar, { class: "avatar", user: profileData.value.userId, displayName: resolvedDisplayName.value, size: 96, disableMenu: "", disableTooltip: "", preloadedUserStatus: avatarUserStatus.value, isNoUser: !profileData.value.isUserAvatarVisible }, null, 8, ["user", "displayName", "preloadedUserStatus", "isNoUser"]) ]), _: 1 }, 16, ["class"])) : (openBlock(), createElementBlock("div", _hoisted_5)), createElementVNode("div", _hoisted_6, [ createElementVNode("div", _hoisted_7, [ profileUrl.value ? (openBlock(), createElementBlock("a", { key: 0, class: "profile-hover-card__profile-link", href: profileUrl.value }, [ createElementVNode("h2", null, toDisplayString(resolvedDisplayName.value), 1) ], 8, _hoisted_8)) : (openBlock(), createElementBlock("h2", _hoisted_9, toDisplayString(resolvedDisplayName.value), 1)), profileData.value.pronouns ? (openBlock(), createElementBlock("span", _hoisted_10, "·")) : createCommentVNode("", true), profileData.value.pronouns ? (openBlock(), createElementBlock("span", _hoisted_11, toDisplayString(profileData.value.pronouns), 1)) : createCommentVNode("", true) ]), userStatus.value.icon || userStatus.value.message ? (openBlock(), createElementBlock("div", _hoisted_12, [ createElementVNode("span", _hoisted_13, [ createElementVNode("span", null, toDisplayString(userStatus.value.icon) + " " + toDisplayString(userStatus.value.message), 1) ]) ])) : createCommentVNode("", true) ]) ]) ]), createElementVNode("div", _hoisted_14, [ createElementVNode("div", _hoisted_15, [ createElementVNode("div", _hoisted_16, [ !unref(isMobile) ? (openBlock(), createBlock(resolveDynamicComponent(profileUrl.value ? "a" : "div"), mergeProps({ key: 0, class: { "profile-hover-card__profile-link": !!profileUrl.value } }, profileLinkProps.value), { default: withCtx(() => [ createVNode(NcAvatar, { class: "avatar", user: profileData.value.userId, displayName: resolvedDisplayName.value, size: 135, disableMenu: "", disableTooltip: "", preloadedUserStatus: avatarUserStatus.value, isNoUser: !profileData.value.isUserAvatarVisible }, null, 8, ["user", "displayName", "preloadedUserStatus", "isNoUser"]) ]), _: 1 }, 16, ["class"])) : createCommentVNode("", true), createElementVNode("div", _hoisted_17, [ __props.actionsLoading && resolvedActions.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_18, [ createVNode(NcLoadingIcon, { size: 20, name: unref(t)("Loading actions") }, null, 8, ["name"]) ])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [ primaryAction.value ? (openBlock(), createBlock(NcButton, mergeProps({ key: 0, variant: "primary", class: "user-actions__primary" }, primaryActionButtonProps.value, { onClick: primaryAction.value.onClick }), createSlots({ default: withCtx(() => [ createTextVNode(" " + toDisplayString(actionDisplayText(primaryAction.value)), 1) ]), _: 2 }, [ primaryAction.value.iconSvg || primaryAction.value.icon ? { name: "icon", fn: withCtx(() => [ primaryAction.value.iconSvg ? (openBlock(), createBlock(unref(NcIconSvgWrapper), { key: 0, svg: primaryAction.value.iconSvg }, null, 8, ["svg"])) : isIconUrl(primaryAction.value.icon) ? (openBlock(), createElementBlock("img", { key: 1, src: primaryAction.value.icon, alt: "", class: "user-actions__primary__icon" }, null, 8, _hoisted_19)) : (openBlock(), createElementBlock("span", { key: 2, "aria-hidden": "true", class: normalizeClass(["user-actions__primary__icon-class", primaryAction.value.icon]) }, null, 2)) ]), key: "0" } : void 0 ]), 1040, ["onClick"])) : createCommentVNode("", true), otherActions.value.length > 0 ? (openBlock(), createBlock(NcActions, { key: 1, class: "user-actions__other", inline: unref(isMobile) ? 5 : 4 }, { default: withCtx(() => [ (openBlock(true), createElementBlock(Fragment, null, renderList(otherActions.value, (action, index) => { return openBlock(), createBlock(resolveDynamicComponent(otherActionComponent(action)), mergeProps({ key: action.id || action.href || index }, { ref_for: true }, otherActionProps(action)), createSlots({ default: withCtx(() => [ createTextVNode(" " + toDisplayString(actionDisplayText(action)), 1) ]), _: 2 }, [ action.iconSvg || action.icon ? { name: "icon", fn: withCtx(() => [ action.iconSvg ? (openBlock(), createBlock(unref(NcIconSvgWrapper), { key: 0, svg: action.iconSvg }, null, 8, ["svg"])) : isIconUrl(action.icon) ? (openBlock(), createElementBlock("img", { key: 1, src: action.icon, alt: "", class: "user-actions__other__icon" }, null, 8, _hoisted_20)) : (openBlock(), createElementBlock("span", { key: 2, "aria-hidden": "true", class: normalizeClass(["user-actions__other__icon-class", action.icon]) }, null, 2)) ]), key: "0" } : void 0 ]), 1040); }), 128)) ]), _: 1 }, 8, ["inline"])) : createCommentVNode("", true) ], 64)) ]) ]), profileEnabled.value ? (openBlock(), createElementBlock("div", _hoisted_21, [ profileData.value.organisation || profileData.value.role || profileData.value.address || localTimeLabel.value ? (openBlock(), createElementBlock("div", _hoisted_22, [ profileData.value.organisation || profileData.value.role ? (openBlock(), createElementBlock("div", _hoisted_23, [ createElementVNode("p", null, [ createVNode(BriefcaseIcon, { class: "detail-icon", size: 16, title: "" }), createTextVNode(" " + toDisplayString(profileData.value.organisation) + " ", 1), profileData.value.organisation && profileData.value.role ? (openBlock(), createElementBlock("span", _hoisted_24, "•")) : createCommentVNode("", true), createTextVNode(" " + toDisplayString(profileData.value.role), 1) ]) ])) : createCommentVNode("", true), profileData.value.address ? (openBlock(), createElementBlock("div", _hoisted_25, [ createElementVNode("p", null, [ createVNode(MapMarkerIcon, { class: "detail-icon", size: 16, title: "" }), createTextVNode(" " + toDisplayString(profileData.value.address), 1) ]) ])) : createCommentVNode("", true), localTimeLabel.value ? (openBlock(), createElementBlock("div", _hoisted_26, [ createElementVNode("p", null, [ createVNode(ClockIcon, { class: "detail-icon", size: 16, title: "" }), createTextVNode(" " + toDisplayString(localTimeLabel.value), 1) ]) ])) : createCommentVNode("", true) ])) : createCommentVNode("", true), profileData.value.headline || profileData.value.biography ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [ profileData.value.headline ? (openBlock(), createElementBlock("h3", _hoisted_27, toDisplayString(profileData.value.headline), 1)) : createCommentVNode("", true), profileData.value.biography ? (openBlock(), createElementBlock("div", _hoisted_28, [ createVNode(NcRichText, { text: profileData.value.biography, useExtendedMarkdown: "" }, null, 8, ["text"]) ])) : createCommentVNode("", true) ], 64)) : createCommentVNode("", true) ])) : createCommentVNode("", true) ]) ]) ], 64)) : createCommentVNode("", true) ], 10, _hoisted_1); }; } }); const NcProfileHoverCard = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-592f6ec3"]]); export { NcProfileHoverCard as default }; //# sourceMappingURL=NcProfileHoverCard.mjs.map