Skip to content

Commit

Permalink
Merge branch 'main' into feat/556
Browse files Browse the repository at this point in the history
  • Loading branch information
paustint committed Nov 26, 2023
2 parents 6446eea + 0674f36 commit a59f19c
Show file tree
Hide file tree
Showing 12 changed files with 80 additions and 77 deletions.
2 changes: 0 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ PRISMA_DEBUG='false'

NX_SFDC_CLIENT_ID_ELECTRON=''
NX_AUTH_AUDIENCE='http://getjetstream.app/app_metadata'

NX_AG_GRID_KEY=''
NX_ROLLBAR_KEY=''
NX_AMPLITUDE_KEY=''

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ export const ViewEditCloneRecord: FunctionComponent<ViewEditCloneRecordProps> =
});
}

function handleCopyToClipboard(format: 'excel' | 'text' | 'json' = 'excel') {
function handleCopyToClipboard(format: 'excel' | 'json' = 'excel') {
if (!initialRecord) {
return;
}
Expand Down Expand Up @@ -589,11 +589,8 @@ export const ViewEditCloneRecord: FunctionComponent<ViewEditCloneRecordProps> =
className="slds-button_last"
dropDownClassName="slds-dropdown_actions"
position="right"
items={[
{ id: 'text', value: 'Copy as Text' },
{ id: 'json', value: 'Copy as JSON' },
]}
onSelected={(item) => handleCopyToClipboard(item as 'excel' | 'text' | 'json')}
items={[{ id: 'json', value: 'Copy as JSON' }]}
onSelected={(item) => handleCopyToClipboard(item as 'excel' | 'json')}
/>
</ButtonGroupContainer>
<button
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { css } from '@emotion/react';
import { ListMetadataResultItem, useListMetadata } from '@jetstream/connected-ui';
import { ANALYTICS_KEYS } from '@jetstream/shared/constants';
import { formatNumber, transformTabularDataToExcelStr } from '@jetstream/shared/ui-utils';
import { copyRecordsToClipboard, formatNumber } from '@jetstream/shared/ui-utils';
import { pluralizeIfMultiple } from '@jetstream/shared/utils';
import { ListMetadataResult, MapOf, SalesforceOrgUi } from '@jetstream/types';
import {
Expand All @@ -17,7 +17,6 @@ import {
ToolbarItemActions,
ToolbarItemGroup,
} from '@jetstream/ui';
import copyToClipboard from 'copy-to-clipboard';
import addMinutes from 'date-fns/addMinutes';
import formatISODate from 'date-fns/formatISO';
import isAfter from 'date-fns/isAfter';
Expand All @@ -29,19 +28,19 @@ import { useRecoilState, useRecoilValue } from 'recoil';
import { applicationCookieState, selectedOrgState } from '../../app-state';
import { useAmplitude } from '../core/analytics';
import * as fromJetstreamEvents from '../core/jetstream-events';
import DeployMetadataDeploymentSidePanel from './DeployMetadataDeploymentSidePanel';
import DeployMetadataDeploymentTable from './DeployMetadataDeploymentTable';
import DeployMetadataLastRefreshedPopover from './DeployMetadataLastRefreshedPopover';
import AddToChangeset from './add-to-changeset/AddToChangeset';
import DeleteMetadataModal from './delete-metadata/DeleteMetadataModal';
import DeployMetadataHistoryModal from './deploy-metadata-history/DeployMetadataHistoryModal';
import DeployMetadataPackage from './deploy-metadata-package/DeployMetadataPackage';
import * as fromDeployMetadataState from './deploy-metadata.state';
import { AllUser, DeployMetadataTableRow, SidePanelType, YesNo } from './deploy-metadata.types';
import { DeployMetadataTableRow, SidePanelType } from './deploy-metadata.types';
import DeployMetadataToOrg from './deploy-to-different-org/DeployMetadataToOrg';
import DeployMetadataDeploymentSidePanel from './DeployMetadataDeploymentSidePanel';
import DeployMetadataDeploymentTable from './DeployMetadataDeploymentTable';
import DeployMetadataLastRefreshedPopover from './DeployMetadataLastRefreshedPopover';
import { convertRowsForExport, convertRowsToMapOfListMetadataResults, getRows } from './utils/deploy-metadata.utils';
import DeployMetadataSelectedItemsBadge from './utils/DeployMetadataSelectedItemsBadge';
import DownloadPackageWithFileSelector from './utils/DownloadPackageWithFileSelector';
import { convertRowsForExport, convertRowsToMapOfListMetadataResults, getRows } from './utils/deploy-metadata.utils';
import ViewOrCompareMetadataModal from './view-or-compare-metadata/ViewOrCompareMetadataModal';

const TABLE_ACTION_CLIPBOARD = 'table-copy-to-clipboard';
Expand Down Expand Up @@ -211,9 +210,9 @@ export const DeployMetadataDeployment: FunctionComponent<DeployMetadataDeploymen
if (id === TABLE_ACTION_DOWNLOAD_MANIFEST) {
handleDownloadActive('manifest');
} else if (id === TABLE_ACTION_CLIPBOARD) {
copyToClipboard(transformTabularDataToExcelStr(convertRowsForExport(rows || [], selectedRows)), { format: 'text/plain' });
copyRecordsToClipboard(convertRowsForExport(rows || [], selectedRows));
} else if (id === TABLE_ACTION_CLIPBOARD_SELECTED) {
copyToClipboard(transformTabularDataToExcelStr(convertRowsForExport(rows || [], selectedRows, true)), { format: 'text/plain' });
copyRecordsToClipboard(convertRowsForExport(rows || [], selectedRows, true));
} else if (id === TABLE_ACTION_DOWNLOAD) {
setExportData(convertRowsForExport(rows || [], selectedRows));
} else if (id === TABLE_ACTION_DOWNLOAD_SELECTED) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const QueryResultsCopyToClipboard: FunctionComponent<QueryResultsCopyToCl
}) => {
const { trackEvent } = useAmplitude();
const [isModalOpen, setIsModalOpen] = useState(false);
const [format, setFormat] = useState<'excel' | 'text' | 'json'>('excel');
const [format, setFormat] = useState<'excel' | 'json'>('excel');
const [whichRecords, setWhichRecords] = useState<WhichRecords>('all');
const [hasFilteredRows, setHasFilteredRows] = useState<boolean>(false);
const [hasPartialSelectedRows, setHasPartialSelectedRows] = useState<boolean>(false);
Expand All @@ -50,7 +50,7 @@ export const QueryResultsCopyToClipboard: FunctionComponent<QueryResultsCopyToCl
setWhichRecords('all');
}, [records, filteredRows, selectedRows]);

async function handleCopyToClipboard(format: 'excel' | 'text' | 'json' = 'excel') {
async function handleCopyToClipboard(format: 'excel' | 'json' = 'excel') {
if (
(records && hasFilteredRows && filteredRows.length < records.length) ||
(records && hasPartialSelectedRows && selectedRows.length < records.length)
Expand All @@ -59,7 +59,6 @@ export const QueryResultsCopyToClipboard: FunctionComponent<QueryResultsCopyToCl
setIsModalOpen(true);
return;
}

copyRecordsToClipboard(records, format, fields);
trackEvent(ANALYTICS_KEYS.query_CopyToClipboard, { isTooling, whichRecords, format });
}
Expand Down Expand Up @@ -110,11 +109,8 @@ export const QueryResultsCopyToClipboard: FunctionComponent<QueryResultsCopyToCl
dropDownClassName="slds-dropdown_actions"
position="right"
disabled={!hasRecords}
items={[
{ id: 'text', value: 'Copy as Text' },
{ id: 'json', value: 'Copy as JSON' },
]}
onSelected={(item) => handleCopyToClipboard(item as 'excel' | 'text' | 'json')}
items={[{ id: 'json', value: 'Copy as JSON' }]}
onSelected={(item) => handleCopyToClipboard(item as 'excel' | 'json')}
/>
</ButtonGroupContainer>
{isModalOpen && (
Expand Down
41 changes: 32 additions & 9 deletions libs/shared/ui-utils/src/lib/shared-ui-data-utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { logger } from '@jetstream/shared/client-logger';
import { describeSObject, genericRequest } from '@jetstream/shared/data';
import { REGEX, flattenRecords, getMapOf, splitArrayToMaxSize } from '@jetstream/shared/utils';
import type {
Expand Down Expand Up @@ -295,15 +296,37 @@ export async function fetchActiveLog(org: SalesforceOrgUi, id: string): Promise<

/**
* Copy records to clipboard in various formats
* Copy the content in both plain text and HTML to be compatible with pasting to excel
* along with other applications at the same time
*/
export function copyRecordsToClipboard(recordsToCopy: any, copyFormat: 'excel' | 'text' | 'json', fields?: Maybe<string[]>) {
if (copyFormat === 'excel' && fields) {
const flattenedData = flattenRecords(recordsToCopy, fields);
copyToClipboard(transformTabularDataToHtml(flattenedData, fields), { format: 'text/html' });
} else if (copyFormat === 'text' && fields) {
const flattenedData = flattenRecords(recordsToCopy, fields);
copyToClipboard(transformTabularDataToExcelStr(flattenedData, fields), { format: 'text/plain' });
} else if (copyFormat === 'json') {
copyToClipboard(JSON.stringify(recordsToCopy, null, 2), { format: 'text/plain' });
export async function copyRecordsToClipboard(
recordsToCopy: any,
copyFormat: 'excel' | 'json' = 'excel',
fields?: Maybe<string[]>,
includeHeader = true
) {
try {
if (copyFormat === 'excel') {
recordsToCopy = fields ? flattenRecords(recordsToCopy, fields) : recordsToCopy;
const clipboardItem = new ClipboardItem({
'text/plain': new Blob([transformTabularDataToExcelStr(recordsToCopy, fields, includeHeader)], { type: 'text/plain' }),
'text/html': new Blob([transformTabularDataToHtml(recordsToCopy, fields, includeHeader)], { type: 'text/html' }),
});
await navigator.clipboard.write([clipboardItem]);
} else if (copyFormat === 'json') {
const clipboardItem = new ClipboardItem({
'text/plain': new Blob([JSON.stringify(recordsToCopy, null, 2)], { type: 'text/plain' }),
});
await navigator.clipboard.write([clipboardItem]);
}
logger.info('[Clipboard][Copied]', { recordsToCopy });
} catch (ex) {
logger.warn('Copy to clipboard failed, trying fallback', ex.message);
if (copyFormat === 'excel' && fields) {
const flattenedData = flattenRecords(recordsToCopy, fields);
copyToClipboard(transformTabularDataToExcelStr(flattenedData, fields, includeHeader), { format: 'text/plain' });
} else if (copyFormat === 'json') {
copyToClipboard(JSON.stringify(recordsToCopy, null, 2), { format: 'text/plain' });
}
}
}
4 changes: 2 additions & 2 deletions libs/shared/ui-utils/src/lib/shared-ui-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,7 @@ export function getValueForExcel(value: any) {
*/
export function transformTabularDataToExcelStr<T = Record<string, unknown>>(
data: Maybe<T>[],
fields?: string[],
fields?: Maybe<string[]>,
includeHeader = true
): string {
if (!Array.isArray(data) || data.length === 0) {
Expand Down Expand Up @@ -1308,7 +1308,7 @@ export function transformTabularDataToExcelStr<T = Record<string, unknown>>(
* @param includeHeader
* @returns
*/
export function transformTabularDataToHtml<T = unknown>(data: T[], fields?: string[], includeHeader = true): string {
export function transformTabularDataToHtml<T = unknown>(data: T[], fields?: Maybe<string[]>, includeHeader = true): string {
if (!Array.isArray(data) || data.length === 0) {
return '';
}
Expand Down
8 changes: 3 additions & 5 deletions libs/ui/src/lib/data-table/DataTableSubqueryRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { queryMore } from '@jetstream/shared/data';
import { formatNumber, transformTabularDataToExcelStr } from '@jetstream/shared/ui-utils';
import { flattenRecord, flattenRecords } from '@jetstream/shared/utils';
import { copyRecordsToClipboard, formatNumber } from '@jetstream/shared/ui-utils';
import { flattenRecord } from '@jetstream/shared/utils';
import { Maybe, SalesforceOrgUi } from '@jetstream/types';
import copyToClipboard from 'copy-to-clipboard';
import type { QueryResult } from 'jsforce';
import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react';
import { RenderCellProps } from 'react-data-grid';
Expand Down Expand Up @@ -100,8 +99,7 @@ export const SubqueryRenderer: FunctionComponent<RenderCellProps<RowWithKey, unk

function handleCopyToClipboard(columns: ColumnWithFilter<any, unknown>[]) {
const fields = columns.map((column) => column.key);
const flattenedData = flattenRecords(records, fields);
copyToClipboard(transformTabularDataToExcelStr(flattenedData, fields), { format: 'text/plain' });
copyRecordsToClipboard(records, 'excel', fields);
}

async function loadMore(org: SalesforceOrgUi, isTooling: boolean) {
Expand Down
13 changes: 4 additions & 9 deletions libs/ui/src/lib/data-table/data-table-utils.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { QueryResults, QueryResultsColumn } from '@jetstream/api-interfaces';
import { logger } from '@jetstream/shared/client-logger';
import { DATE_FORMATS, RECORD_PREFIX_MAP } from '@jetstream/shared/constants';
import { transformTabularDataToExcelStr, transformTabularDataToHtml } from '@jetstream/shared/ui-utils';
import { ensureBoolean, flattenRecords, getIdFromRecordUrl, pluralizeFromNumber } from '@jetstream/shared/utils';
import { copyRecordsToClipboard } from '@jetstream/shared/ui-utils';
import { ensureBoolean, getIdFromRecordUrl, pluralizeFromNumber } from '@jetstream/shared/utils';
import { MapOf, Maybe } from '@jetstream/types';
import copyToClipboard from 'copy-to-clipboard';
import isAfter from 'date-fns/isAfter';
import isBefore from 'date-fns/isBefore';
import isSameDay from 'date-fns/isSameDay';
Expand Down Expand Up @@ -821,13 +820,9 @@ export function copySalesforceRecordTableDataToClipboard(
}
if (recordsToCopy.length) {
if (format === 'json') {
copyToClipboard(JSON.stringify(recordsToCopy, null, 2), { format: 'text/plain' });
} else if (format === 'excel') {
const flattenedData = flattenRecords(recordsToCopy, fieldsToCopy);
copyToClipboard(transformTabularDataToHtml(flattenedData, fieldsToCopy), { format: 'text/html' });
copyRecordsToClipboard(recordsToCopy, 'json');
} else {
const flattenedData = flattenRecords(recordsToCopy, fieldsToCopy);
copyToClipboard(transformTabularDataToExcelStr(flattenedData, fieldsToCopy, includeHeader), { format: 'text/plain' });
copyRecordsToClipboard(recordsToCopy, 'excel', fieldsToCopy, includeHeader);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { queryWithCache } from '@jetstream/shared/data';
import { useRollbar } from '@jetstream/shared/ui-utils';
import { FieldWrapper, SalesforceOrgUi } from '@jetstream/types';
import copyToClipboard from 'copy-to-clipboard';
import React, { Fragment, FunctionComponent, useCallback, useEffect, useRef, useState } from 'react';
import { Fragment, FunctionComponent, useCallback, useEffect, useRef, useState } from 'react';
import { Spinner } from '../..';
import ErrorBoundaryWithoutContent from '../utils/ErrorBoundaryWithoutContent';
import Icon from '../widgets/Icon';
Expand Down
7 changes: 2 additions & 5 deletions libs/ui/src/lib/sobject-field-list/WhereIsThisFieldUsed.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { css } from '@emotion/react';
import { transformTabularDataToExcelStr, useNonInitialEffect } from '@jetstream/shared/ui-utils';
import { copyRecordsToClipboard, useNonInitialEffect } from '@jetstream/shared/ui-utils';
import { ListItem, SalesforceOrgUi } from '@jetstream/types';
import copyToClipboard from 'copy-to-clipboard';
import { Fragment, FunctionComponent, useState } from 'react';
import FileDownloadModal from '../file-download-modal/FileDownloadModal';
import EmptyState from '../illustrations/EmptyState';
Expand Down Expand Up @@ -61,9 +60,7 @@ export const QueryWhereIsThisUsed: FunctionComponent<QueryWhereIsThisUsedProps>
}

function handleCopyToClipboard() {
copyToClipboard(transformTabularDataToExcelStr(exportData, ['Reference Type', 'Reference Label', 'Namespace']), {
format: 'text/plain',
});
copyRecordsToClipboard(exportData, 'excel', ['Reference Type', 'Reference Label', 'Namespace']);
}

return (
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"url": "https://github.com/jetstreamapp/jetstream"
},
"author": "Jetstream",
"version": "3.1.0",
"version": "3.2.0",
"license": "GNU Lesser General Public License v3.0",
"engines": {
"node": ">=16 <=18"
Expand Down Expand Up @@ -210,7 +210,7 @@
"postcss": "8.4.19",
"postcss-preset-env": "7",
"prettier": "2.7.0",
"prisma": "^5.3.1",
"prisma": "^5.6.0",
"react-refresh": "^0.10.0",
"release-it": "^15.6.0",
"sass": "1.55.0",
Expand Down Expand Up @@ -248,7 +248,7 @@
"@opentelemetry/exporter-trace-otlp-grpc": "^0.27.0",
"@opentelemetry/sdk-node": "^0.27.0",
"@popperjs/core": "^2.4.0",
"@prisma/client": "^5.3.1",
"@prisma/client": "^5.6.0",
"@react-aria/dialog": "^3.1.4",
"@react-aria/focus": "^3.5.0",
"@react-aria/overlays": "^3.7.2",
Expand Down
36 changes: 18 additions & 18 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6497,22 +6497,22 @@
resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz"
integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==

"@prisma/client@^5.3.1":
version "5.3.1"
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.3.1.tgz#fc7fc2d91e814cc4fe18a4bc5e78bf851c26985e"
integrity sha512-ArOKjHwdFZIe1cGU56oIfy7wRuTn0FfZjGuU/AjgEBOQh+4rDkB6nF+AGHP8KaVpkBIiHGPQh3IpwQ3xDMdO0Q==
"@prisma/client@^5.6.0":
version "5.6.0"
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.6.0.tgz#1c15932250d5658fe0127e62faf4ecd96a877259"
integrity sha512-mUDefQFa1wWqk4+JhKPYq8BdVoFk9NFMBXUI8jAkBfQTtgx8WPx02U2HB/XbAz3GSUJpeJOKJQtNvaAIDs6sug==
dependencies:
"@prisma/engines-version" "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59"
"@prisma/engines-version" "5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee"

"@prisma/engines-version@5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59":
version "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59"
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59.tgz#7eb6f5c6b7628b8b39df55c903f411528a6f761c"
integrity sha512-y5qbUi3ql2Xg7XraqcXEdMHh0MocBfnBzDn5GbV1xk23S3Mq8MGs+VjacTNiBh3dtEdUERCrUUG7Z3QaJ+h79w==
"@prisma/engines-version@5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee":
version "5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee"
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee.tgz#57b003ab5e1ea1523b5cdd7f06b24ebcf5c7fd8c"
integrity sha512-UoFgbV1awGL/3wXuUK3GDaX2SolqczeeJ5b4FVec9tzeGbSWJboPSbT0psSrmgYAKiKnkOPFSLlH6+b+IyOwAw==

"@prisma/engines@5.3.1":
version "5.3.1"
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.3.1.tgz#53cc72a5ed176dc27d22305fe5569c64cc78b381"
integrity sha512-6QkILNyfeeN67BNEPEtkgh3Xo2tm6D7V+UhrkBbRHqKw9CTaz/vvTP/ROwYSP/3JT2MtIutZm/EnhxUiuOPVDA==
"@prisma/engines@5.6.0":
version "5.6.0"
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.6.0.tgz#82c445aa10633bbc0388aa2d6e411a0bd94c9439"
integrity sha512-Mt2q+GNJpU2vFn6kif24oRSBQv1KOkYaterQsi0k2/lA+dLvhRX6Lm26gon6PYHwUM8/h8KRgXIUMU0PCLB6bw==

"@prisma/prisma-fmt-wasm@3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a":
version "3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a"
Expand Down Expand Up @@ -21482,12 +21482,12 @@ pretty-hrtime@^1.0.3:
resolved "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz"
integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==

prisma@^5.3.1:
version "5.3.1"
resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.3.1.tgz#a0932c1c1a5ed4ff449d064b193d9c7e94e8bf77"
integrity sha512-Wp2msQIlMPHe+5k5Od6xnsI/WNG7UJGgFUJgqv/ygc7kOECZapcSz/iU4NIEzISs3H1W9sFLjAPbg/gOqqtB7A==
prisma@^5.6.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.6.0.tgz#ae2c27fdfb4d53be7f7dafb50d6b8b7f55c93aa5"
integrity sha512-EEaccku4ZGshdr2cthYHhf7iyvCcXqwJDvnoQRAJg5ge2Tzpv0e2BaMCp+CbbDUwoVTzwgOap9Zp+d4jFa2O9A==
dependencies:
"@prisma/engines" "5.3.1"
"@prisma/engines" "5.6.0"

proc-log@^3.0.0:
version "3.0.0"
Expand Down

0 comments on commit a59f19c

Please sign in to comment.