diff --git a/libs/blocks/locui-create/input-actions/view.js b/libs/blocks/locui-create/input-actions/view.js index 319400f6ab..c2a9ac48d8 100644 --- a/libs/blocks/locui-create/input-actions/view.js +++ b/libs/blocks/locui-create/input-actions/view.js @@ -2,7 +2,7 @@ import { html } from '../../../deps/htm-preact.js'; import StepControls from '../components/stepControls.js'; import useInputActions from './index.js'; import { prevStep, project } from '../store.js'; -import { LOCALIZATION_TYPES } from '../utils/constant.js'; +import { PROJECT_TYPES, PROJECT_TYPE_LABELS } from '../utils/constant.js'; import Toast from '../components/toast.js'; function TranslateActions({ languageCount, handleActionSelect, handleWorkflowSelect }) { @@ -101,11 +101,11 @@ export default function InputActionsView() { return html`
-

${project.value.type === LOCALIZATION_TYPES.translation ? 'Translate' : 'Rollout'}

+

${PROJECT_TYPE_LABELS[project.value.type]}

Project Name: ${project.value.name || 'n/a'}

- ${project.value.type === LOCALIZATION_TYPES.translation ? html`<${TranslateActions} languageCount=${languageCount} handleActionSelect=${handleActionSelect} handleWorkflowSelect=${handleWorkflowSelect} />` + ${project.value.type === PROJECT_TYPES.translation ? html`<${TranslateActions} languageCount=${languageCount} handleActionSelect=${handleActionSelect} handleWorkflowSelect=${handleWorkflowSelect} />` : html`<${RolloutActions} languageCount=${languageCount} />`}

diff --git a/libs/blocks/locui-create/input-locale/index.js b/libs/blocks/locui-create/input-locale/index.js index a5948d807e..128783c960 100644 --- a/libs/blocks/locui-create/input-locale/index.js +++ b/libs/blocks/locui-create/input-locale/index.js @@ -10,7 +10,7 @@ import { setLocale, updateDraftProject, } from '../store.js'; -import { LOCALIZATION_TYPES } from '../utils/constant.js'; +import { PROJECT_TYPES } from '../utils/constant.js'; export default function useInputLocale() { const [selectedRegion, setSelectedRegion] = useState( @@ -26,8 +26,8 @@ export default function useInputLocale() { const [apiError, setApiError] = useState(''); useEffect(() => { - if (project.value.type === LOCALIZATION_TYPES.rollout - || project.value.type === LOCALIZATION_TYPES.translation) { + if (project.value.type === PROJECT_TYPES.rollout + || project.value.type === PROJECT_TYPES.translation) { locales.value = locales.value.filter((locItem) => locItem.workflow !== 'Transcreation' && locItem.livecopies !== ''); } // eslint-disable-next-line react-hooks/exhaustive-deps @@ -51,7 +51,7 @@ export default function useInputLocale() { return Object.entries(groupedLocales).map(([language, localeList]) => { const languageItem = { language, - locales: project.value.type === LOCALIZATION_TYPES.translation ? [] : localeList, + locales: project.value.type === PROJECT_TYPES.translation ? [] : localeList, langCode: languageCodes[language], }; return languageItem; @@ -154,7 +154,7 @@ export default function useInputLocale() { const prefillActionAndWorkflow = (languages) => { const storedLanguages = project.value?.languages ?? []; if (storedLanguages.length < 1) { - return languages.map((lang) => ({ ...lang, action: project.value.type === LOCALIZATION_TYPES.translation ? 'Translate' : 'Rollout', workflow: '' })); + return languages.map((lang) => ({ ...lang, action: project.value.type === PROJECT_TYPES.translation ? 'Translate' : 'Rollout', workflow: '' })); } let iteratorIndex = 0; const prefilledLanguages = []; @@ -167,7 +167,7 @@ export default function useInputLocale() { workflow: workflow || '', }; if (!action) { - prefillLanguage.action = project.value.type === LOCALIZATION_TYPES.translation ? 'Translate' : 'Rollout'; + prefillLanguage.action = project.value.type === PROJECT_TYPES.translation ? 'Translate' : 'Rollout'; } prefilledLanguages.push(prefillLanguage); iteratorIndex += 1; diff --git a/libs/blocks/locui-create/input-locale/view.js b/libs/blocks/locui-create/input-locale/view.js index 49e32c5bfc..6aa0836475 100644 --- a/libs/blocks/locui-create/input-locale/view.js +++ b/libs/blocks/locui-create/input-locale/view.js @@ -1,7 +1,7 @@ import { html } from '../../../deps/htm-preact.js'; import useInputLocale from './index.js'; import StepControls from '../components/stepControls.js'; -import { LOCALIZATION_TYPES } from '../utils/constant.js'; +import { PROJECT_TYPES } from '../utils/constant.js'; import Toast from '../components/toast.js'; export default function InputLocales() { @@ -118,13 +118,13 @@ export default function InputLocales() {
-

${project.value.type === LOCALIZATION_TYPES.translation ? 'Translate' : 'Rollout'}

+

${project.value.type === PROJECT_TYPES.translation ? 'Translate' : 'Rollout'}

Project Name: ${project.value.name || 'n/a'}

<${RenderRegion} />
<${RenderLanguage} /> - ${project.value.type !== LOCALIZATION_TYPES.translation && selectedLocale.length > 0 + ${project.value.type !== PROJECT_TYPES.translation && selectedLocale.length > 0 && html`
Selected Locales
diff --git a/libs/blocks/locui-create/input-urls/index.js b/libs/blocks/locui-create/input-urls/index.js index 146800cadf..c7bcf41a45 100644 --- a/libs/blocks/locui-create/input-urls/index.js +++ b/libs/blocks/locui-create/input-urls/index.js @@ -1,7 +1,7 @@ import { findDeepFragments } from '../../locui/actions/index.js'; import { validateUrlsFormat } from '../../locui/loc/index.js'; import { origin } from '../../locui/utils/franklin.js'; -import { LOCALIZATION_TYPES } from '../utils/constant.js'; +import { PROJECT_TYPES } from '../utils/constant.js'; export function validateProjectName(name) { if (name && !/^[a-zA-Z0-9-]+$/.test(name)) { @@ -86,7 +86,7 @@ export async function findFragments(urls) { return validateUrlsFormat(foundFragments, true); } export function getInitialName(type) { - const prefix = type === LOCALIZATION_TYPES.rollout ? 'rollout' : 'translate'; + const prefix = type === PROJECT_TYPES.rollout ? 'rollout' : 'translate'; let date = new Date().toISOString(); if (date.indexOf('.') > -1) { date = date.slice(0, date.indexOf('.')); diff --git a/libs/blocks/locui-create/input-urls/view.js b/libs/blocks/locui-create/input-urls/view.js index 989b5e8d02..1052ba9f19 100644 --- a/libs/blocks/locui-create/input-urls/view.js +++ b/libs/blocks/locui-create/input-urls/view.js @@ -6,6 +6,7 @@ import { } from '../../../deps/htm-preact.js'; import FragmentsSection from '../fragments/view.js'; import { + authenticated, createDraftProject, nextStep, project, @@ -25,13 +26,13 @@ import { getInitialName, } from './index.js'; import { getUrls } from '../../locui/loc/index.js'; -import { URL_SEPARATOR_PATTERN } from '../utils/constant.js'; +import { PROJECT_TYPES, PROJECT_TYPE_LABELS, URL_SEPARATOR_PATTERN } from '../utils/constant.js'; import Toast from '../components/toast.js'; export default function InputUrls() { - const [type, setType] = useState('translation'); - const [name, setName] = useState(''); - const [htmlFlow, setHtmlFlow] = useState(false); + const [type, setType] = useState(PROJECT_TYPES.translation); + const [name, setName] = useState(getInitialName(type)); + const [htmlFlow, setHtmlFlow] = useState(true); const [editBehavior, setEditBehavior] = useState(''); const [urlsStr, setUrlsStr] = useState(''); const [fragmentsEnabled, setFragmentsEnabled] = useState(false); @@ -144,8 +145,8 @@ export default function InputUrls() { setProject({ type, name, - htmlFlow: type === 'translation' ? htmlFlow : false, - editBehavior: type === 'rollout' ? editBehavior : '', + htmlFlow: type === PROJECT_TYPES.translation ? htmlFlow : false, + editBehavior: type === PROJECT_TYPES.rollout ? editBehavior : '', urls: urlsStr.split(/,|\n/), fragments, }); @@ -163,21 +164,23 @@ export default function InputUrls() { } useEffect(() => { - setType(project.value?.type || 'translation'); - setName(project.value?.name || getInitialName('translation')); - setHtmlFlow(project.value?.htmlFlow || false); - setEditBehavior(project.value?.editBehavior || ''); - setUrlsStr(project.value?.urls?.join('\n') || ''); - setFragmentsEnabled(project.value?.fragments?.length > 0); - setFragments(project.value?.fragments || []); - if ( - project.value?.fragments?.length > 0 - && project.value?.urls.length > 0 - ) { - fetchFragments(project.value?.urls?.join('\n')); + if (project.value) { + setType(project.value?.type); + setName(project.value?.name); + setHtmlFlow(project.value?.htmlFlow || true); + setEditBehavior(project.value?.editBehavior || ''); + setUrlsStr(project.value?.urls?.join('\n')); + setFragmentsEnabled(project.value?.fragments?.length > 0); + setFragments(project.value?.fragments); + if ( + project.value?.fragments?.length > 0 + && project.value?.urls.length > 0 + ) { + fetchFragments(project.value?.urls?.join('\n')); + } } // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [project.value]); const handleUrlsBlur = () => { if (urlsStr && !errors.urlsStr) { @@ -203,23 +206,23 @@ export default function InputUrls() {
Localization${' '} - - ${type.substring(0, 1).toUpperCase() + type.substring(1)} + - ${PROJECT_TYPE_LABELS[type]}
-
-
handleTypeChange('translation')} - > - Translation -
-
handleTypeChange('rollout')} - > - Rollout + ${!projectCreated.value && html` +
+ ${[PROJECT_TYPES.translation, PROJECT_TYPES.rollout].map((pType) => html` +
handleTypeChange(pType)} + > + ${PROJECT_TYPE_LABELS[pType]} +
+ `)}
-
+ `} +
* Enter Project Name
@@ -235,7 +238,7 @@ export default function InputUrls() {
- ${type === 'translation' + ${type === PROJECT_TYPES.translation && html`
HTML Localization Flow
@@ -247,7 +250,7 @@ export default function InputUrls() { />
`} - ${type === 'rollout' + ${type === PROJECT_TYPES.rollout && html`
* Regional Edit Behavior
@@ -260,7 +263,7 @@ export default function InputUrls() { - + ${errors.editBehavior && html`
@@ -329,7 +332,10 @@ export default function InputUrls() { />`}
- <${StepControls} nextDisabled=${errorPresent} onNext=${handleNext} /> + <${StepControls} + nextDisabled=${!authenticated.value || errorPresent} + onNext=${handleNext} + />
`; diff --git a/libs/blocks/locui-create/locui-create.css b/libs/blocks/locui-create/locui-create.css index 245d343c3c..b3da975509 100644 --- a/libs/blocks/locui-create/locui-create.css +++ b/libs/blocks/locui-create/locui-create.css @@ -358,7 +358,6 @@ body { height: 100%; z-index: 100; background: rgba(0, 0, 0, 0.1); - pointer-events: none; display: flex; align-items: center; justify-content: center; diff --git a/libs/blocks/locui-create/locui-create.js b/libs/blocks/locui-create/locui-create.js index 42c4da0205..5c0be26057 100644 --- a/libs/blocks/locui-create/locui-create.js +++ b/libs/blocks/locui-create/locui-create.js @@ -1,21 +1,47 @@ -import { html, render, useEffect } from '../../deps/htm-preact.js'; +import { html, render, useEffect, useState } from '../../deps/htm-preact.js'; import InputLocales from './input-locale/view.js'; import InputUrls from './input-urls/view.js'; -import { currentStep, env, fetchLocaleDetails, getUserToken, loading } from './store.js'; +import { + currentStep, + env, + fetchDraftProject, + fetchLocaleDetails, + getUserToken, + loading, + project, +} from './store.js'; import StepTracker from './components/stepTracker.js'; import InputActions from './input-actions/view.js'; import Header from '../milostudio-header/milostudio-header.js'; import Sidenav from '../milostudio-sidenav/sidenav.js'; import { getConfig, loadStyle } from '../../utils/utils.js'; import { getEnvQueryParam } from './utils/utils.js'; +import Toast from './components/toast.js'; function Create() { + const [toast, setToast] = useState({ type: '', message: '' }); + useEffect(() => { const setup = async () => { try { await fetchLocaleDetails(); await getUserToken(); env.value = getEnvQueryParam(); + + /* Fetch draft project if project key is found in url params */ + const searchParams = new URLSearchParams(window.location.search); + const projectKey = searchParams.get('projectKey'); + if (projectKey) { + const error = await fetchDraftProject(projectKey); + if (error) { + setToast({ type: 'error', message: error }); + } else { + setToast({ + type: 'info', + message: `Project ${project.value.name} fetched succesfully.`, + }); + } + } } catch (error) { // console.error('Error fetching locale details:', error); } @@ -44,6 +70,15 @@ function Create() { && html`
`} + + ${toast.message + && html` + <${Toast} + message=${toast.message} + type=${toast.type} + onClose=${() => setToast({ ...toast, message: '' })} + /> + `}
`; } diff --git a/libs/blocks/locui-create/store.js b/libs/blocks/locui-create/store.js index 5d80dcb1b6..6d512dedd2 100644 --- a/libs/blocks/locui-create/store.js +++ b/libs/blocks/locui-create/store.js @@ -11,6 +11,7 @@ import { export const telemetry = { application: { appName: 'Adobe Localization' } }; +export const authenticated = signal(false); export const currentStep = signal(1); export const loading = signal(false); export const project = signal(null); @@ -59,8 +60,10 @@ export async function getUserToken() { try { await login({ scopes, telemetry }); userToken = accessToken.value; + authenticated.value = true; } catch { console.error('Sharepoint login failed. Unable to get User-Token!'); + authenticated.value = false; } loading.value = false; return userToken; @@ -126,6 +129,7 @@ export async function createDraftProject() { error = responseJson.error; } } catch (err) { + // eslint-disable-next-line no-console console.error(err); } loading.value = false; @@ -148,7 +152,11 @@ export async function updateDraftProject(publish = false) { }; try { const url = await getMilocUrl(); - const opts = { method: 'POST', headers: { 'User-Token': userToken, 'Content-Type': 'application/json' }, body: JSON.stringify(body) }; + const opts = { + method: 'POST', + headers: { 'User-Token': userToken, 'Content-Type': 'application/json' }, + body: JSON.stringify(body), + }; const resp = await fetch(`${url}update-draft-project`, opts); const respJson = await resp.json(); if (resp.ok) { @@ -165,3 +173,54 @@ export async function updateDraftProject(publish = false) { loading.value = false; return error; } + +export async function fetchDraftProject(projectKey) { + if (!projectKey) { + return 'Project key has not been provided.'; + } + + const userToken = await getUserToken(); + if (!userToken) { + return 'Unable to login to Sharepoint.'; + } + + let error = 'Failed to fetch project details. Please try again!'; + loading.value = true; + + try { + const url = await getMilocUrl(); + const options = { + method: 'POST', + headers: { 'User-Token': userToken, 'Content-Type': 'application/json' }, + }; + const response = await fetch( + `${url}fetch-draft-project?project=${projectKey}`, + options, + ); + const resJson = await response.json(); + if (response.ok) { + setProject({ + type: resJson.projectType === 'rollout' ? 'rollout' : 'translation', + name: resJson.projectName, + htmlFlow: resJson.settings?.useHtmlFlow, + editBehavior: resJson.settings?.regionalEditBehaviour, + urls: resJson.urls, + fragments: [], + }); + projectInfo.value = { + ...projectInfo.value, + projectKey, + }; + projectCreated.value = true; + error = ''; + } + if (resJson.error) { + error = resJson.error; + } + } catch (e) { + // eslint-disable-next-line no-console + console.error(e); + } + loading.value = false; + return error; +} diff --git a/libs/blocks/locui-create/utils/constant.js b/libs/blocks/locui-create/utils/constant.js index 46c6ebe5eb..ad7b05121c 100644 --- a/libs/blocks/locui-create/utils/constant.js +++ b/libs/blocks/locui-create/utils/constant.js @@ -5,3 +5,12 @@ export const LOCALIZATION_TYPES = { rollout: 'rollout', translation: 'translation', }; +export const PROJECT_TYPES = { + translation: 'localization', + rollout: 'rollout', +}; +export const PROJECT_TYPE_LABELS = { + localization: 'Translation', + translation: 'Translation', + rollout: 'Rollout', +}; diff --git a/libs/blocks/locui-create/utils/utils.js b/libs/blocks/locui-create/utils/utils.js index 9a5c1834e1..7f79593dee 100644 --- a/libs/blocks/locui-create/utils/utils.js +++ b/libs/blocks/locui-create/utils/utils.js @@ -1,7 +1,6 @@ import getServiceConfig from '../../../utils/service-config.js'; import { origin } from '../../locui/utils/franklin.js'; import { env } from '../store.js'; -import { LOCALIZATION_TYPES } from './constant.js'; export function getTenantName() { try { @@ -53,12 +52,12 @@ export const createPayload = (project) => { return { tenantBaseUrl: origin, projectName: project.value.name, - projectType: project.value.type === LOCALIZATION_TYPES.rollout ? 'rollout' : 'localization', + projectType: project.value.type, referrer: 'studio', languages: project.value.languages, urls, settings: { - env: 'stage', + env: env.value, regionalEditBehaviour: project.value.editBehavior, useHtmlFlow: project.value.htmlFlow, }, @@ -66,14 +65,11 @@ export const createPayload = (project) => { }; export async function getMilocUrl() { - if (env.value === 'dev') { - return 'https://14257-miloc-dev.adobeioruntime.net/api/v1/web/miloc-0.0.1/'; - } const { miloc } = await getServiceConfig(origin, env.value); return miloc.url; } export function getEnvQueryParam() { const urlSearchParams = new URLSearchParams(window.location.search); - return urlSearchParams.get('env') ?? 'dev'; + return urlSearchParams.get('env') ?? 'local'; }