mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-05 00:09:35 +00:00
156 lines
5.1 KiB
Vue
156 lines
5.1 KiB
Vue
<!-- Copyright 2026 OpenObserve Inc.
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
-->
|
|
|
|
<template>
|
|
<!-- an empty passcode would substitute into a valid-looking but non-functional snippet -->
|
|
<OBanner
|
|
v-if="passcodeForbidden && contentNeedsPasscode"
|
|
variant="warning"
|
|
data-test="copy-content-passcode-forbidden"
|
|
:content="t('ingestion.passcodeForbiddenMessage')"
|
|
/>
|
|
<div v-else class="rounded-default copy-content-block bg-surface-subtle relative overflow-hidden">
|
|
<div class="absolute top-2 right-2 z-10">
|
|
<OButton
|
|
data-test="rum-copy-btn"
|
|
variant="ghost"
|
|
size="icon-xs-sq"
|
|
@click="copyToClipboardFn()"
|
|
>
|
|
<OIcon name="content-copy" size="sm" />
|
|
<OTooltip :content="t('common.copy')" side="top" />
|
|
</OButton>
|
|
</div>
|
|
<pre
|
|
data-test="rum-content-text"
|
|
class="m-0 p-3 pe-10 text-sm leading-5 wrap-break-word whitespace-pre-wrap"
|
|
>{{ computedContent }}</pre>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
// @ts-nocheck
|
|
import { defineComponent, ref, type PropType } from "vue";
|
|
import { type I18nText, useI18nTyped } from "@/types/i18n";
|
|
import { useStore } from "vuex";
|
|
import { useRouter } from "vue-router";
|
|
import { copyToClipboard } from "@/utils/clipboard";
|
|
import analytics from "@/services/product_analytics";
|
|
import { maskText, b64EncodeStandard } from "../utils/zincutils";
|
|
import OButton from "@/lib/core/Button/OButton.vue";
|
|
import OIcon from "@/lib/core/Icon/OIcon.vue";
|
|
import OTooltip from "@/lib/overlay/Tooltip/OTooltip.vue";
|
|
import OBanner from "@/lib/feedback/Banner/OBanner.vue";
|
|
|
|
const PASSCODE_PLACEHOLDERS = ["[PASSCODE]", "[BASIC_PASSCODE]"];
|
|
|
|
export default defineComponent({
|
|
name: "CopyContent",
|
|
components: { OButton, OIcon, OTooltip, OBanner },
|
|
props: {
|
|
content: {
|
|
type: String as unknown as PropType<I18nText>,
|
|
default: "", // Default value for content prop (empty string in this case)
|
|
},
|
|
displayContent: {
|
|
type: String,
|
|
default: "", // Default value for displayContent prop (empty string in this case)
|
|
},
|
|
},
|
|
setup(props) {
|
|
const store = useStore();
|
|
const router = useRouter();
|
|
const { t } = useI18nTyped();
|
|
const email = ref(store.state.userInfo.email);
|
|
const passcode = ref(store.state.organizationData.organizationPasscode);
|
|
const basicPasscode = ref();
|
|
|
|
const replaceValues = (data: string, isMask: boolean = false) => {
|
|
email.value = store.state.userInfo.email;
|
|
passcode.value = store.state.organizationData.organizationPasscode;
|
|
basicPasscode.value = b64EncodeStandard(
|
|
`${email.value}:${store.state.organizationData.organizationPasscode}`,
|
|
);
|
|
if (isMask) {
|
|
return data
|
|
.replaceAll("[EMAIL]", maskText(email.value))
|
|
.replaceAll("[PASSCODE]", maskText(passcode.value))
|
|
.replaceAll("[BASIC_PASSCODE]", maskText(basicPasscode.value));
|
|
} else {
|
|
return data
|
|
.replaceAll("[EMAIL]", email.value)
|
|
.replaceAll("[PASSCODE]", passcode.value)
|
|
.replaceAll("[BASIC_PASSCODE]", basicPasscode.value);
|
|
}
|
|
};
|
|
|
|
const copyToClipboardFn = () => {
|
|
const content = replaceValues(props.content, false);
|
|
copyToClipboard(content, t, {
|
|
successMessage: t("common.contentCopiedSuccessfully"),
|
|
errorMessage: t("common.copyContentError"),
|
|
timeout: 5000,
|
|
}).then((copied) => {
|
|
if (copied) {
|
|
analytics.track("snippet_copied", {
|
|
route: router?.currentRoute.value.name,
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
const displayData = ref(props.displayContent || props.content);
|
|
const computedContent = ref();
|
|
computedContent.value = replaceValues(displayData.value, true);
|
|
|
|
const refreshData = () => {
|
|
computedContent.value = replaceValues(displayData.value, true);
|
|
};
|
|
|
|
return {
|
|
t,
|
|
store,
|
|
copyToClipboardFn,
|
|
displayData,
|
|
replaceValues,
|
|
computedContent,
|
|
refreshData,
|
|
};
|
|
},
|
|
computed: {
|
|
computedData() {
|
|
return this.store.state.organizationData.organizationPasscode;
|
|
},
|
|
passcodeForbidden() {
|
|
return !!this.store.state.organizationData.organizationPasscodeForbidden;
|
|
},
|
|
contentNeedsPasscode() {
|
|
const source = this.displayContent || this.content || "";
|
|
return PASSCODE_PLACEHOLDERS.some((token) => source.includes(token));
|
|
},
|
|
},
|
|
watch: {
|
|
content(newVal: string) {
|
|
this.displayData = newVal;
|
|
this.refreshData();
|
|
},
|
|
computedData() {
|
|
this.refreshData();
|
|
},
|
|
},
|
|
});
|
|
</script>
|