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

MWPW-166823 - [Floodgate] hlx 5 upgrade to support the floodgate flow #3745

Merged
merged 10 commits into from
Mar 3, 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
5 changes: 3 additions & 2 deletions libs/blocks/floodgateui/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { origin, preview } from '../../locui/utils/franklin.js';
import { decorateSections } from '../../../utils/utils.js';
import { getUrls } from '../../locui/loc/index.js';
import { validateUrlsFormat } from '../floodgate/index.js';
import { isUrl } from '../utils/url.js';

export const showRolloutOptions = signal(false);

Expand Down Expand Up @@ -92,7 +93,7 @@ async function findPageFragments(path) {

if (accDupe || dupe) return acc;
const fragmentUrl = new URL(`${origin}${pathname}`);
fragmentUrl.alt = fragment.textContent;
fragmentUrl.alt = isUrl(fragment.textContent) ? fragment.textContent : originalUrl;
acc.push(fragmentUrl);
return acc;
}, []);
Expand All @@ -119,7 +120,7 @@ async function findDeepFragments(path) {
searched.push(search.pathname);
}
}
return fragments.length ? fragments : [];
return fragments.length ? getUrls(fragments) : [];
}

export async function findFragments() {
Expand Down
14 changes: 12 additions & 2 deletions libs/blocks/floodgateui/floodgate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,28 @@
let resourcePath;
let previewPath;

export function validateOrigin(urlStr) {
try {
const url = new URL(urlStr);
const origins = [url.origin.replace('.aem.', '.hlx.'), url.origin.replace('.hlx.', '.aem.')];
return origins.includes(origin);
} catch {
return false;
}
}

export function validateUrlsFormat(projectUrls, removeMedia = false) {
projectUrls.forEach((projectUrl, idx) => {
const urlObj = getUrl(projectUrl);
const url = isUrl(urlObj.alt) ?? urlObj;
if (url.origin !== origin) {
if (!validateOrigin(url.origin)) {
const aemUrl = url.hostname?.split('--').length === 3;
url.valid = !aemUrl ? 'not AEM url' : 'not same domain';
}
if ((/\.(gif|jpg|jpeg|tiff|png|webp)$/i).test(url.pathname)) {
url.valid = 'media';
}
projectUrls[idx] = Array.isArray(projectUrls[idx]) ? [url] : url;
projectUrls[idx] = Array.isArray(projectUrls[idx]) ? [urlObj] : urlObj;
});
if (removeMedia) {
return projectUrls.filter((url) => getUrl(url).valid !== 'media');
Expand Down Expand Up @@ -94,7 +104,7 @@
if (missingKeys.length > 0) {
setStatus('details', 'error', 'Missing required URL parameter(s)');
} else {
console.error(error);

Check warning on line 107 in libs/blocks/floodgateui/floodgate/index.js

View workflow job for this annotation

GitHub Actions / Running eslint

[eslint] reported by reviewdog 🐶 Unexpected console statement. Raw Output: {"ruleId":"no-console","severity":1,"message":"Unexpected console statement.","line":107,"column":7,"nodeType":"MemberExpression","messageId":"unexpected","endLine":107,"endColumn":20}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions libs/blocks/floodgateui/utils/miloc.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {
allowSendForLoc,

Check failure on line 2 in libs/blocks/floodgateui/utils/miloc.js

View workflow job for this annotation

GitHub Actions / Running eslint

[eslint] reported by reviewdog 🐶 'allowSendForLoc' is defined but never used. Raw Output: {"ruleId":"no-unused-vars","severity":2,"message":"'allowSendForLoc' is defined but never used.","line":2,"column":3,"nodeType":"Identifier","messageId":"unusedVar","endLine":2,"endColumn":18}
allowSyncToLangstore,

Check failure on line 3 in libs/blocks/floodgateui/utils/miloc.js

View workflow job for this annotation

GitHub Actions / Running eslint

[eslint] reported by reviewdog 🐶 'allowSyncToLangstore' is defined but never used. Raw Output: {"ruleId":"no-unused-vars","severity":2,"message":"'allowSyncToLangstore' is defined but never used.","line":3,"column":3,"nodeType":"Identifier","messageId":"unusedVar","endLine":3,"endColumn":23}
heading,
languages,

Check failure on line 5 in libs/blocks/floodgateui/utils/miloc.js

View workflow job for this annotation

GitHub Actions / Running eslint

[eslint] reported by reviewdog 🐶 'languages' is defined but never used. Raw Output: {"ruleId":"no-unused-vars","severity":2,"message":"'languages' is defined but never used.","line":5,"column":3,"nodeType":"Identifier","messageId":"unusedVar","endLine":5,"endColumn":12}
projectStatus,

Check failure on line 6 in libs/blocks/floodgateui/utils/miloc.js

View workflow job for this annotation

GitHub Actions / Running eslint

[eslint] reported by reviewdog 🐶 'projectStatus' is defined but never used. Raw Output: {"ruleId":"no-unused-vars","severity":2,"message":"'projectStatus' is defined but never used.","line":6,"column":3,"nodeType":"Identifier","messageId":"unusedVar","endLine":6,"endColumn":16}
serviceStatus,

Check failure on line 7 in libs/blocks/floodgateui/utils/miloc.js

View workflow job for this annotation

GitHub Actions / Running eslint

[eslint] reported by reviewdog 🐶 'serviceStatus' is defined but never used. Raw Output: {"ruleId":"no-unused-vars","severity":2,"message":"'serviceStatus' is defined but never used.","line":7,"column":3,"nodeType":"Identifier","messageId":"unusedVar","endLine":7,"endColumn":16}
allowRollout,

Check failure on line 8 in libs/blocks/floodgateui/utils/miloc.js

View workflow job for this annotation

GitHub Actions / Running eslint

[eslint] reported by reviewdog 🐶 'allowRollout' is defined but never used. Raw Output: {"ruleId":"no-unused-vars","severity":2,"message":"'allowRollout' is defined but never used.","line":8,"column":3,"nodeType":"Identifier","messageId":"unusedVar","endLine":8,"endColumn":15}
serviceStatusDate,

Check failure on line 9 in libs/blocks/floodgateui/utils/miloc.js

View workflow job for this annotation

GitHub Actions / Running eslint

[eslint] reported by reviewdog 🐶 'serviceStatusDate' is defined but never used. Raw Output: {"ruleId":"no-unused-vars","severity":2,"message":"'serviceStatusDate' is defined but never used.","line":9,"column":3,"nodeType":"Identifier","messageId":"unusedVar","endLine":9,"endColumn":20}
allActionStatus,
copyStatusCheck,
deleteStatusCheck,
Expand All @@ -20,8 +20,8 @@
} from './state.js';
import { accessToken } from '../../../tools/sharepoint/state.js';
import { origin, getStatus } from '../../locui/utils/franklin.js';
import { setExcelStatus, setStatus } from './status.js';

Check failure on line 23 in libs/blocks/floodgateui/utils/miloc.js

View workflow job for this annotation

GitHub Actions / Running eslint

[eslint] reported by reviewdog 🐶 'setExcelStatus' is defined but never used. Raw Output: {"ruleId":"no-unused-vars","severity":2,"message":"'setExcelStatus' is defined but never used.","line":23,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":23,"endColumn":24}
import getServiceConfig from '../../../utils/service-config.js';

Check failure on line 24 in libs/blocks/floodgateui/utils/miloc.js

View workflow job for this annotation

GitHub Actions / Running eslint

[eslint] reported by reviewdog 🐶 'getServiceConfig' is defined but never used. Raw Output: {"ruleId":"no-unused-vars","severity":2,"message":"'getServiceConfig' is defined but never used.","line":24,"column":8,"nodeType":"Identifier","messageId":"unusedVar","endLine":24,"endColumn":24}
import '../../../deps/md5.min.js';

const DOT_MILO = '/.milo/config.json';
Expand Down Expand Up @@ -120,6 +120,7 @@
export async function fetchStatusAction() {
// fetch copy status
const config = await getServiceConfigFg(origin);
if (!config || !heading.value.env) return{};
const paramsFg = await getParamsFg(config);
const excelPath = paramsFg.projectExcelPath;
const env = heading.value.env;
Expand Down
4 changes: 3 additions & 1 deletion libs/blocks/locui/actions/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* eslint-disable no-await-in-loop */
/* eslint-disable no-restricted-syntax */
import { heading, urls, languages, allowSyncToLangstore, allowSendForLoc, allowRollout } from '../utils/state.js';
import {
heading, urls, languages, allowSyncToLangstore, allowSendForLoc, allowRollout,
} from '../utils/state.js';
import { setExcelStatus, setStatus } from '../utils/status.js';
import { origin, preview } from '../utils/franklin.js';
import { decorateSections } from '../../../utils/utils.js';
Expand Down
23 changes: 19 additions & 4 deletions libs/blocks/locui/utils/franklin.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
const ADMIN = 'https://admin.hlx.page';
import { SLD } from '../../../utils/utils.js';

const ADMIN = 'https://admin.hlx.page';
const urlParams = new URLSearchParams(window.location.search);
const owner = urlParams.get('owner') || 'adobecom';
const repo = urlParams.get('repo') || 'milo';
export const origin = `https://main--${repo}--${owner}.hlx.page`;
export const origin = `https://main--${repo}--${owner}.${SLD}.page`;

// Temporary fix until https://github.com/adobe/helix-admin/issues/2831 is fixed.
function fixPreviewDomain(json) {
if (SLD === 'aem') {
if (json?.preview?.url) {
json.preview.url = json.preview.url.replace('.hlx.', '.aem.');
}
if (json?.live?.url) {
json.live.url = json.live.url.replace('.hlx.', '.aem.');
}
}
}

export async function preview(path) {
const url = `${ADMIN}/preview/${owner}/${repo}/main${path}`;
const resp = await fetch(url, { method: 'POST' });
const json = await resp.json();
fixPreviewDomain(json);
return json;
}

export async function getStatus(path = '', editUrl = 'auto', fgFlag = false, fgColor = null) {
let url = `${ADMIN}/status/${owner}/${fgFlag ? `${repo}-${fgColor}` : repo}/main${path}`;
export async function getStatus(path = '', editUrl = 'auto') {
let url = `${ADMIN}/status/${owner}/${repo}/main${path}`;
url = editUrl ? `${url}?editUrl=${editUrl}` : url;
const resp = await fetch(url, { cache: 'reload' });
const json = await resp.json();
fixPreviewDomain(json);
return json;
}
5 changes: 3 additions & 2 deletions libs/tools/sharepoint/shared.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import getServiceConfig from '../../utils/service-config.js';
import { SLD } from '../../utils/utils.js';

const MOCK_REFERRER = 'https://adobe.sharepoint.com/:x:/r/sites/adobecom/_layouts/15/Doc.aspx?sourcedoc=%7B654BFAD2-84A7-442D-A13D-18DE87A405B7%7D';

Expand All @@ -14,7 +15,7 @@ export async function getSharePointDetails(hlxOrigin) {
}

export function getItemId() {
const referrer = new URLSearchParams(window.location.search).get('referrer') || MOCK_REFERRER;
const referrer = new URLSearchParams(window.location.search).get('referrer');
const sourceDoc = referrer?.match(/sourcedoc=([^&]+)/)[1];
const sourceId = decodeURIComponent(sourceDoc);
return sourceId.slice(1, -1);
Expand All @@ -24,5 +25,5 @@ export function getSiteOrigin() {
const search = new URLSearchParams(window.location.search);
const repo = search.get('repo');
const owner = search.get('owner');
return repo && owner ? `https://main--${repo}--${owner}.hlx.live` : window.location.origin;
return repo && owner ? `https://main--${repo}--${owner}.${SLD}.page` : window.location.origin;
}
94 changes: 92 additions & 2 deletions libs/utils/sidekick.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,69 @@
function stylePublish(sk) {
const pubPlg = sk.shadowRoot.querySelector('.publish.plugin');
if (!pubPlg) return;
const style = document.createElement('style');
const span = document.createElement('span');
span.textContent = 'Are you sure? This will publish to production.';
const btn = pubPlg.querySelector('button');
const publishStyles = `
.plugin.update {
--bg-color: rgb(129 27 14);
--text-color: #fff0f0;

color-scheme: light dark;
display: flex;
order: 100;
}
.publish.plugin > button {
background: var(--bg-color);
border-color: #b46157;
color: var(--text-color);
}
.publish.plugin > button > span {
display: none;
background: var(--bg-color);
border-radius: 4px;
line-height: 1.2rem;
padding: 8px 12px;
position: absolute;
top: 34px;
left: 50%;
transform: translateX(-50%);
width: 150px;
white-space: pre-wrap;
}
.publish.plugin > button:hover > span {
display: block;
color: var(--text-color);
}
.publish.plugin > button > span:before {
content: '';
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid var(--bg-color);
position: absolute;
text-align: center;
top: -6px;
left: 50%;
transform: translateX(-50%);
}
`;
style.append(publishStyles);
pubPlg.prepend(style);
btn.append(span);
}

// loadScript and loadStyle are passed in to avoid circular dependencies
export default function init({ createTag, loadBlock, loadScript, loadStyle }) {
// manifest v3
const sendToCaasListener = async (e) => {
const { host, project, ref: branch, repo, owner } = e.detail.data.config;
// eslint-disable-next-line import/no-unresolved
const { sendToCaaS } = await import('https://milo.adobe.com/tools/send-to-caas/send-to-caas.js');
sendToCaaS({ host, project, branch, repo, owner }, loadScript, loadStyle);
};

const checkSchemaListener = async (e) => {
const checkSchemaListener = async () => {
const schema = document.querySelector('script[type="application/ld+json"]');
if (schema === null) return;
const resultsUrl = 'https://search.google.com/test/rich-results?url=';
Expand All @@ -29,10 +85,44 @@ export default function init({ createTag, loadBlock, loadScript, loadStyle }) {
sendToCaaS({ host, project, branch, repo, owner }, loadScript, loadStyle);
});

const sk = document.querySelector('helix-sidekick');
const sk = document.querySelector('aem-sidekick, helix-sidekick');

// Add plugin listeners here
sk.addEventListener('custom:send-to-caas', sendToCaasListener);
sk.addEventListener('custom:check-schema', checkSchemaListener);
sk.addEventListener('custom:preflight', preflightListener);

// Color code publish button
stylePublish(sk);
}

function onSkLoaded(callback) {
// sidekick nextGen
const observer = new MutationObserver(() => {
const sidekick = document.querySelector('aem-sidekick');
if (sidekick) {
observer.disconnect();
callback(sidekick);
}
});
observer.observe(document.body, { childList: true, subtree: true });

// sidekick v1 ready event
document.addEventListener('sidekick-ready', () => {
callback(document.querySelector('helix-sidekick'));
}, { once: true });
}

export function connectSK(status, standby = null) {
const sidekick = document.querySelector('aem-sidekick, helix-sidekick');
if (sidekick) {
sidekick.addEventListener('statusfetched', status);
sidekick.addEventListener('status-fetched', status);
} else {
standby?.();
onSkLoaded((sk) => {
sk?.addEventListener('statusfetched', status);
sk?.addEventListener('status-fetched', status);
});
}
}
Loading
Loading