Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy correct content of attribute in AttributeViewer based on attribute content type #855

Merged
merged 1 commit into from
Feb 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

46 changes: 17 additions & 29 deletions src/components/Attributes/AttributeViewer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import cx from 'classnames';
import CustomTable, { TableDataRow, TableHeader } from 'components/CustomTable';
import { selectors as enumSelectors, getEnumLabel } from 'ducks/enums';
import { useCallback, useMemo, useState } from 'react';
Expand All @@ -14,13 +13,12 @@ import {
isCustomAttributeModelArray,
} from 'types/attributes';
import { MetadataItemModel, MetadataModel } from 'types/locations';
import { NameAndUuidDto, PlatformEnum, Resource } from 'types/openapi';
import { getAttributeContent } from 'utils/attributes/attributes';
import { AttributeContentType, NameAndUuidDto, PlatformEnum, Resource } from 'types/openapi';
import { getAttributeContent, getAttributeCopyValue } from 'utils/attributes/attributes';
import { useCopyToClipboard } from 'utils/common-hooks';
import { actions as userInterfaceActions } from '../../../ducks/user-interface';
import ContentValueField from '../../Input/DynamicContent/ContentValueField';
import WidgetButtons, { WidgetButtonProps } from '../../WidgetButtons';
import styles from './attributeViewer.module.scss';

export enum ATTRIBUTE_VIEWER_TYPE {
ATTRIBUTE,
Expand Down Expand Up @@ -57,28 +55,11 @@ export default function AttributeViewer({

const onCopyContentClick = useCallback(
(attribute: AttributeResponseModel) => {
let textToCopy = '';
if (!attribute?.content?.length) return;
// if (attribute.content.length > 1) textToCopy = attribute?.content?.map((content) => content.data).join(', ');
// if (attribute.content.length === 1) textToCopy = attribute.content[0]?.reference.toString();

// check if reference is there or if no reference then use .data to copy
const textToCopy = getAttributeCopyValue(attribute.contentType, attribute.content);

if (attribute.content.length > 1) {
textToCopy = attribute.content
.map((content) => {
if (content.reference) {
return content.reference;
}
return content.data;
})
.join(', ');
}
if (attribute.content.length === 1) {
textToCopy = attribute.content[0]?.reference?.toString() || attribute.content[0]?.data.toString();
}

if (attribute) {
if (attribute && textToCopy) {
copyToClipboard(textToCopy, 'Custom Attribute content was copied to clipboard', 'Failed to copy to clipboard');
}
},
Expand Down Expand Up @@ -210,11 +191,18 @@ export default function AttributeViewer({
{getContent(attribute.contentType, attribute.content)}
{resource && renderSourceObjectsButton(attribute, resource)}
</>,
<i
className={cx('fa fa-copy', styles.copyContentButton)}
onClick={() => {
onCopyContentClick(attribute);
}}
<WidgetButtons
key="copy"
buttons={[
{
icon: 'copy',
disabled: AttributeContentType.Secret === attribute.contentType,
onClick: () => {
onCopyContentClick(attribute);
},
tooltip: 'Copy to clipboard',
},
]}
/>,
],
}),
Expand Down Expand Up @@ -254,7 +242,7 @@ export default function AttributeViewer({
} else {
buttons.push({
icon: 'copy',
disabled: false,
disabled: AttributeContentType.Secret === attribute.contentType,
tooltip: 'Copy to clipboard',
onClick: () => {
onCopyContentClick(attribute);
Expand Down
37 changes: 36 additions & 1 deletion src/utils/attributes/attributes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
isDataAttributeModel,
} from 'types/attributes';
import { AttributeContentType, CodeBlockAttributeContent, FileAttributeContentData, SecretAttributeContent } from 'types/openapi';
import { utf8ToBase64 } from 'utils/common-utils';
import { base64ToUtf8, utf8ToBase64 } from 'utils/common-utils';
import { getFormattedDateTime } from 'utils/dateUtil';
import CodeBlock from '../../components/Attributes/CodeBlock';

Expand All @@ -22,6 +22,41 @@ export const attributeFieldNameTransform: { [name: string]: string } = {
cryptographyProvider: 'Cryptography Provider',
notificationProvider: 'Notification Provider',
};
export const getAttributeCopyValue = (contentType: AttributeContentType, content: BaseAttributeContentModel[] | undefined) => {
if (!content) return undefined;

const mapping = (content: BaseAttributeContentModel): string | undefined => {
switch (contentType) {
case AttributeContentType.Codeblock:
if (typeof content.data === 'object' && 'code' in content.data) return base64ToUtf8(content.data.code);
return content.data.toString();
case AttributeContentType.Credential:
if (typeof content.data === 'object' && 'name' in content.data) return content.data.name;
return content.data.toString();
case AttributeContentType.File:
if (typeof content.data === 'object' && 'content' in content.data) return base64ToUtf8(content.data.content);
return content.data.toString();
case AttributeContentType.Object:
return JSON.stringify(content.data);
case AttributeContentType.Boolean:
return content.data ? 'true' : 'false';
case AttributeContentType.Time:
return content.data.toString();
case AttributeContentType.Date:
return content.data.toString();
case AttributeContentType.Datetime:
return getFormattedDateTime(content.data.toString());
case AttributeContentType.Float:
case AttributeContentType.Integer:
case AttributeContentType.String:
case AttributeContentType.Text:
return content.data.toString();
case AttributeContentType.Secret:
return undefined;
}
};
return content.map(mapping).join(', ');
};

export const getAttributeContent = (contentType: AttributeContentType, content: BaseAttributeContentModel[] | undefined) => {
if (!content) return 'Not set';
Expand Down
Loading