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

Adding option to open Explorer/Content Editor for datasource items in the "Assign Content Item" dialog #15

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ It is a work in progress with only one feature for the moment.
## ⚙️ Features

- Connecting XM Cloud Pages to your local XM Cloud instance
- Opening Explorer / Content Editor from 'Assign content item' dialog

## ⬇️ Download

Expand Down
110 changes: 110 additions & 0 deletions content-script/datasource-viewer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
declare const chrome: any;
declare const browser: any;

type QueryParams = {
organization: string | null;
tenantName: string | null;
scLang: string | null;
scSite: string | null;
scItemId: string | null;
};

const getQueryParam = (param: string): string | null => {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
return urlParams.get(param);
};

const constructExplorerUrl = (queryParams: QueryParams): string => {
const { organization, tenantName, scLang, scSite, scItemId } = queryParams;
return `https://explorer.sitecorecloud.io/columns?organization=${organization}&tenantName=${tenantName}&sc_lang=${scLang}&sc_site=${scSite}&sc_itemid=${scItemId}`;
};

const constructContentEditorUrl = (queryParams: QueryParams): string => {
const { organization, tenantName, scLang, scItemId } = queryParams;
return `https://xmc-${tenantName}.sitecorecloud.io/sitecore/shell/Applications/Content%20Editor.aspx?sc_bw=1&organization=${organization}&sc_lang=${scLang}&fo=${scItemId}`;
};

const createLinkSpan = (explorerUrl: string, contentEditorUrl: string): HTMLSpanElement => {
const linkSpan = document.createElement('span');
linkSpan.classList.add('xmcloud-extension-links');

const explorerLink = createLinkElement(explorerUrl, 'Explorer');
const contentEditorLink = createLinkElement(contentEditorUrl, 'Content Editor');

linkSpan.appendChild(document.createTextNode('Open in '));
linkSpan.appendChild(explorerLink);
linkSpan.appendChild(document.createTextNode(' or '));
linkSpan.appendChild(contentEditorLink);

return linkSpan;
};

const createLinkElement = (url: string, text: string): HTMLAnchorElement => {
const linkElement = document.createElement('a');
linkElement.classList.add('xmcloud-extension-link');
linkElement.href = url;
linkElement.innerText = text;
linkElement.target = '_blank';
return linkElement;
};

const datasourceViewer = () => {

// Choose the storage API based on the browser
const storageAPI = chrome?.storage?.sync || browser.storage.sync;

// Check if storageAPI is defined (if running in a non-extension context)
if (!storageAPI) {
console.error('Storage API is not available. Make sure you are running in a supported browser environment.');
return;
}

// Retrieve extension settings
storageAPI.get('datasourceEnabled').then((result) => {
const isDatasourceEnabled = result?.datasourceEnabled ?? true;

// Check if the feature is enabled before starting the observer
if (isDatasourceEnabled) {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((addedNode) => {
if (addedNode instanceof HTMLElement && addedNode.closest('app-datasource-picker')) {
console.debug('DOM changed from extension within app-datasource-picker');

const elementsWithDataItemId = addedNode.querySelectorAll('[data-itemid]') as NodeListOf<HTMLElement>;

elementsWithDataItemId.forEach((element: HTMLElement) => {
const itemId = element.getAttribute('data-itemid');
const existingLinkSpan = element.querySelector('.xmcloud-extension-links');

if (!existingLinkSpan && itemId) {
const queryParams: QueryParams = {
organization: getQueryParam('organization'),
tenantName: getQueryParam('tenantName'),
scLang: getQueryParam('sc_lang'),
scSite: getQueryParam('sc_site'),
scItemId: itemId,
};

const explorerUrl = constructExplorerUrl(queryParams);
const contentEditorUrl = constructContentEditorUrl(queryParams);
const linkSpan = createLinkSpan(explorerUrl, contentEditorUrl);

element.appendChild(linkSpan);
}
});
}
});
});
});

observer.observe(document.body, {
childList: true,
subtree: true,
});
}
});
};

export { datasourceViewer };
7 changes: 7 additions & 0 deletions content-script/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Import the content script logic here
import { datasourceViewer } from './datasource-viewer';

// Start content script logics
datasourceViewer();

// Add further content scripts here
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"compile:tsc": "tsc",
"compile:vite": "run-p compile:vite:*",
"compile:vite:web": "vite build",
"compile:vite:js": "vite build --config vite.content.config.ts",
"preview": "vite preview",
"start": "run-s start:chrome",
"start:chrome": "run-p start:chrome:*",
Expand Down
43 changes: 39 additions & 4 deletions popup/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ import {
} from '@chakra-ui/react'
import UnsupportedUrl from './unsupportedUrl'
import { getActiveBrowserTab } from './browserUtils'
import { mdiInformationOutline } from '@mdi/js'
import { mdiInformationOutline, mdiCogOutline } from '@mdi/js'
import { SiGithub } from '@icons-pack/react-simple-icons'
import LocalCmUrlForm from './localCmUrlForm'
import Settings from './settings'

const App = () => {
const [initialized, setInitialized] = useState(false)
Expand All @@ -41,8 +42,8 @@ const App = () => {
}

return url.startsWith('https://pages.sitecorecloud.io') ||
url.startsWith('https://pages.sitecore.io') ||
url.startsWith('https://symphony.sitecorecloud.io')
url.startsWith('https://pages.sitecore.io') ||
url.startsWith('https://symphony.sitecorecloud.io')
}

function handleInfoButtonClick() {
Expand All @@ -55,6 +56,16 @@ const App = () => {
onClose();
}

function handleSettingsButtonClick() {
popupHeight.current = 'md'
onOpen();
}

function handleSettingsSectionClose() {
popupHeight.current = ''
onClose();
}

// Initialization - Called when the popup is open
useEffect(() => {
if (!initialized) {
Expand All @@ -78,7 +89,7 @@ const App = () => {
return (
<ChakraProvider theme={sitecoreTheme} toastOptions={toastOptions}>
<Box width='md' height={popupHeight.current}>
<Box bg='white' shadow='base' overflow='visible' height='14' padding='1' zIndex='3'>
<Box bg='white' shadow='base' overflow='visible' height='14' padding='1' zIndex='3' >
<Flex>
<Flex padding='2'>
<Image src='https://sitecorecontenthub.stylelabs.cloud/api/public/content/740b04f7a7ca404e96d69319fb98f6b0' alt='Sitecore XM Cloud Logo' height='8' />
Expand Down Expand Up @@ -127,6 +138,30 @@ const App = () => {
</DrawerBody>
</DrawerContent>
</Drawer>

<Drawer onClose={handleSettingsSectionClose} isOpen={isOpen} size='sm'>
<DrawerOverlay />
<DrawerContent>
<DrawerCloseButton />
<DrawerHeader>XM Cloud Extension Settings</DrawerHeader>
<DrawerBody>
<Settings />
</DrawerBody>
</DrawerContent>
</Drawer>

<Box bg='white' shadow='base' overflow='visible' height='14' padding='1' zIndex='3' >
<Flex>
<Spacer />
<IconButton
icon={<Icon><path d={mdiCogOutline} /></Icon>}
variant='ghost'
margin='1'
aria-label={''}
onClick={handleSettingsButtonClick}
/>
</Flex>
</Box>
</Box>
</ChakraProvider>
)
Expand Down
89 changes: 89 additions & 0 deletions popup/settings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
declare const chrome: any;
declare const browser: any;

import {
Box,
Flex,
FormControl,
FormLabel,
SimpleGrid,
Spacer,
Stack,
Switch,
Text,
Tooltip,
Wrap,
} from '@chakra-ui/react';
import React, { useState, useEffect } from 'react';

const Settings = () => {
const [datasourceEnabled, setDatasourceEnabled] = useState(true);

useEffect(() => {
// Load extension settings

if (chrome?.storage) {
chrome.storage.sync.get('datasourceEnabled', (result: { datasourceEnabled?: boolean }) => {
setDatasourceEnabled(result.datasourceEnabled ?? true);
});
} else if (browser?.storage) {
browser.storage.sync.get('datasourceEnabled', (result: { datasourceEnabled?: boolean }) => {
setDatasourceEnabled(result.datasourceEnabled ?? true);
});
}
}, []);

const handleSwitchChange = () => {
// Update extension settings when the switch is toggled
const newDatasourceState = !datasourceEnabled;
setDatasourceEnabled(newDatasourceState);

if (chrome?.storage) {
chrome.storage.sync.set({ datasourceEnabled: newDatasourceState });
}
else if (browser?.storage) {
browser.storage.sync.set({ datasourceEnabled: newDatasourceState });
}
};

return (
<Stack spacing='3'>
<Text>
Configure your XM Cloud extension settings here.
</Text>

{/* Feature Section */}
<Box>
<Text fontWeight='semibold'>
Feature Settings:
</Text>
</Box>

{/* Feature list */}
<Box>
<FormControl as={SimpleGrid}>
<Flex>
<Tooltip
label="Displays direct Explorer/Content Editor link for data source items in the 'Assign Content Item' dialog">
<FormLabel htmlFor='datasourceSwitch'>
Enable Datasource Viewer:
</FormLabel>
</Tooltip>
<Spacer />
<Switch
id='datasourceSwitch'
isChecked={datasourceEnabled}
onChange={handleSwitchChange}
/>

</Flex>
</FormControl>
{/* Additional feature switches can be added here */}
</Box>
<Wrap>
</Wrap>
</Stack>
);
};

export default Settings;
22 changes: 22 additions & 0 deletions public/content/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.xmcloud-extension-link {

color: #18181b;
}

.xmcloud-extension-links {
text-decoration: none;
margin-right:10px;
}

.xmcloud-extension-links a {
text-decoration: underline; /* Add underline to links */
}


.node:hover{
text-decoration: unset !important;
}

.node:hover > :not(.xmcloud-extension-links){
text-decoration: underline !important;
}
15 changes: 14 additions & 1 deletion public/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@
"description": "Browser extension that improves Sitecore XM Cloud user experience.",
"homepage_url": "https://github.com/jflheureux/Sitecore-XM-Cloud-Extensions",
"version": "1.0.0",
"content_scripts": [
{
"matches": [
"https://pages.sitecorecloud.io/*",
"https://pages.sitecore.io/*",
"https://symphony.sitecorecloud.io/*"
],
"run_at": "document_idle",
"js": ["./contentScript/index.js"],
"css": ["./content/style.css"]
}
],
"background": {
"service_worker": "./background/background.js"
},
Expand All @@ -19,7 +31,8 @@
}
},
"permissions": [
"scripting"
"scripting",
"storage"
],
"host_permissions": [
"https://pages.sitecorecloud.io/*",
Expand Down
19 changes: 19 additions & 0 deletions public/manifestv2.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@
"description": "Browser extension that improves Sitecore XM Cloud user experience.",
"homepage_url": "https://github.com/jflheureux/Sitecore-XM-Cloud-Extensions",
"version": "1.0.0",
"content_scripts": [
{
"matches": [
"https://pages.sitecorecloud.io/*",
"https://pages.sitecore.io/*",
"https://symphony.sitecorecloud.io/*"
],
"run_at": "document_idle",
"js": ["./contentScript/index.js"],
"css": ["./content/style.css"]
}
],
"browser_specific_settings": {
"gecko": {
"id": "[email protected]"
}
},

"background": {
"page": "./background/index.html",
"persistent": false
Expand All @@ -17,6 +35,7 @@
},
"permissions": [
"scripting",
"storage",
"https://pages.sitecorecloud.io/*",
"https://pages.sitecore.io/*",
"https://symphony.sitecorecloud.io/*"
Expand Down
Binary file added screenshots/screen4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading