@nextcloud/vue
Version:
Nextcloud vue components
826 lines (825 loc) • 33.4 kB
JavaScript
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