Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import copy from 'copy-to-clipboard';
import Icon from 'components/Icon/Icon.react';
import generatePath from 'lib/generatePath';
import styles from './AggregationPanel.scss';

// Text Element Component
Expand All @@ -26,7 +27,11 @@ export const KeyValueElement = ({ item, appName, style, showNote }) => {
const renderValue = ({ value, url, isRelativeUrl }) => {
if (url) {
return (
<a href={isRelativeUrl ? `apps/${appName}/${url}` : url} target="_blank" rel="noreferrer">
<a
href={isRelativeUrl ? generatePath({ slug: appName }, url, true) : url}
target="_blank"
rel="noreferrer"
>
{value}
</a>
);
Expand Down
3 changes: 2 additions & 1 deletion src/components/PermissionsDialog/PermissionsDialog.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,8 @@ export default class PermissionsDialog extends React.Component {
]);
return generatePath(
this.context,
`browser/${className}?filters=${encodeURIComponent(filters)}`
`browser/${className}?filters=${encodeURIComponent(filters)}`,
true
);
}

Expand Down
7 changes: 3 additions & 4 deletions src/dashboard/Data/Views/Views.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,10 +447,9 @@ class Views extends TableView {
url.match(/<script/i)
) {
url = '#';
} else {
url = value.isRelativeUrl
? `apps/${this.context.slug}/${url}${value.urlQuery ? `?${new URLSearchParams(value.urlQuery).toString()}` : ''}`
: url;
} else if (value.isRelativeUrl) {
const query = value.urlQuery ? `?${new URLSearchParams(value.urlQuery).toString()}` : '';
url = generatePath(this.context, `${url}${query}`, true);
}
// Sanitize text
let text = value.text;
Expand Down
43 changes: 43 additions & 0 deletions src/lib/tests/generatePath.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @jest-environment jsdom
*/
/*
* Copyright (c) 2016-present, Parse, LLC
* All rights reserved.
*
* This source code is licensed under the license found in the LICENSE file in
* the root directory of this source tree.
*/
jest.dontMock('../generatePath');

function loadGeneratePath(mountPath) {
if (mountPath === undefined) {
delete window.PARSE_DASHBOARD_PATH;
} else {
window.PARSE_DASHBOARD_PATH = mountPath;
}
let generatePath;
jest.isolateModules(() => {
generatePath = require('../generatePath').default;
});
return generatePath;
}

const app = { slug: 'myApp' };

describe('generatePath', () => {
it('returns a root-relative path by default, regardless of mount path', () => {
const generatePath = loadGeneratePath('/dashboard/');
expect(generatePath(app, 'browser/_User')).toBe('/apps/myApp/browser/_User');
});

it('prepends the mount path when prependMountPath is true and a mount path is set', () => {
const generatePath = loadGeneratePath('/dashboard/');
expect(generatePath(app, 'browser/_User', true)).toBe('/dashboard/apps/myApp/browser/_User');
});

it('falls back to a root-relative path when prependMountPath is true but no mount path is set', () => {
const generatePath = loadGeneratePath(undefined);
expect(generatePath(app, 'browser/_User', true)).toBe('/apps/myApp/browser/_User');
});
});
Loading