diff --git a/packages/storefront/src/decap-cms/collections/get-configs-coll.ts b/packages/storefront/src/decap-cms/collections/get-configs-coll.ts new file mode 100644 index 000000000..1c0bad78d --- /dev/null +++ b/packages/storefront/src/decap-cms/collections/get-configs-coll.ts @@ -0,0 +1,422 @@ +export type CmsCollOptions = { + domain?: string; + baseDir: string; + locale: string; + maxFileSize: number; + markdownOptions: Record; +}; + +const getConfigsColl = ({ + baseDir, + maxFileSize, + markdownOptions, +}: CmsCollOptions) => ({ + name: 'config', + label: { + en: 'Settings & layout', + pt: 'Configurações e layout', + }, + description: { + en: 'General settings for site identity and metadata', + pt: 'Configurações gerais para identidade e metadados do site', + }, + delete: false, + editor: { + preview: false, + }, + files: [ + { + name: 'settings', + label: { + en: 'General config', + pt: 'Configurações gerais', + }, + file: `${baseDir}content/settings.json`, + editor: { + preview: true, + }, + fields: [ + { + label: 'e-com.plus Store ID', + name: 'storeId', + widget: 'hidden', + }, + { + label: 'Repository', + name: 'repository', + widget: 'hidden', + }, + { + label: { + en: 'Domain name', + pt: 'Domínio', + }, + name: 'domain', + widget: 'string', + }, + { + label: { + en: 'Store name', + pt: 'Nome da loja', + }, + name: 'name', + widget: 'string', + }, + { + label: { + en: 'Short description', + pt: 'Descrição curta', + }, + name: 'description', + widget: 'text', + }, + { + label: { + en: 'Logo', + pt: 'Logomarca', + }, + name: 'logo', + widget: 'image', + media_library: { + config: { + max_file_size: maxFileSize, + }, + }, + }, + { + label: { + en: 'Icon', + pt: 'Ícone', + }, + name: 'icon', + widget: 'image', + media_library: { + config: { + max_file_size: maxFileSize, + }, + }, + }, + { + label: { + en: 'Primary color', + pt: 'Cor primária', + }, + name: 'primaryColor', + widget: 'color', + }, + { + label: { + en: 'Secondary color', + pt: 'Cor secundária', + }, + name: 'secondaryColor', + widget: 'color', + required: false, + }, + { + label: { + en: 'Contact email', + pt: 'E-mail de contato', + }, + name: 'email', + widget: 'string', + required: false, + }, + { + label: { + en: 'Service telephone', + pt: 'Telefone de atendimento', + }, + name: 'phone', + widget: 'string', + required: false, + }, + { + label: { + en: 'Store address', + pt: 'Endereço da loja', + }, + name: 'address', + widget: 'string', + required: false, + }, + { + label: { + en: 'Corporate name', + pt: 'Razão social da empresa', + }, + name: 'corporateName', + widget: 'string', + }, + { + label: { + en: 'Store document number', + pt: 'CNPJ', + }, + name: 'docNumber', + widget: 'string', + }, + { + label: { + en: 'Service links', + pt: 'Links de atendimento', + }, + name: 'serviceLinks', + widget: 'list', + summary: '{{fields.title}}', + fields: [ + { + label: { + en: 'Title', + pt: 'Título', + }, + name: 'title', + widget: 'string', + }, + { + label: 'Link', + name: 'href', + widget: 'string', + }, + ], + }, + { + label: { + en: 'Payment methods', + pt: 'Formas de pagamento', + }, + name: 'paymentMethods', + widget: 'select', + multiple: true, + options: [ + 'pix', + 'visa', + 'mastercard', + 'elo', + 'amex', + 'hipercard', + 'boleto', + 'diners', + 'discover', + ], + }, + { + label: 'WhatsApp', + name: 'whatsapp', + widget: 'string', + required: false, + }, + { + label: 'Instagram', + name: 'instagram', + widget: 'string', + required: false, + }, + { + label: 'Facebook', + name: 'facebook', + widget: 'string', + required: false, + }, + { + label: 'X / Twitter', + name: 'twitter', + widget: 'string', + required: false, + }, + { + label: 'YouTube', + name: 'youtube', + widget: 'string', + required: false, + }, + { + label: 'TikTok', + name: 'tiktok', + widget: 'string', + required: false, + }, + { + label: 'Pinterest', + name: 'pinterest', + widget: 'string', + required: false, + }, + { + label: 'Threads', + name: 'threads', + widget: 'string', + required: false, + }, + { + label: { + en: 'Default locale', + pt: 'Língua padrão', + }, + name: 'lang', + widget: 'select', + options: [ + { + label: 'Português', + value: 'pt_br', + }, + { + label: 'Inglês', + value: 'en_us', + }, + ], + default: 'pt_br', + }, + { + label: { + en: 'Currency code', + pt: 'Código da moeda', + }, + name: 'currency', + widget: 'hidden', + default: 'BRL', + }, + { + label: { + en: 'Currency symbol', + pt: 'Símbolo da moeda', + }, + name: 'currencySymbol', + widget: 'hidden', + default: 'R$', + }, + { + label: { + en: 'Country code', + pt: 'Código do país', + }, + name: 'countryCode', + widget: 'hidden', + default: 'BR', + }, + { + name: 'modules', + widget: 'hidden', + }, + { + name: 'cartUrl', + widget: 'hidden', + }, + { + name: 'checkoutUrl', + widget: 'hidden', + }, + { + name: 'accountUrl', + widget: 'hidden', + }, + { + name: 'ordersUrl', + widget: 'hidden', + }, + { + name: 'favoritesUrl', + widget: 'hidden', + }, + { + name: 'metafields', + widget: 'hidden', + }, + ], + }, + { + name: 'layout', + label: { + en: 'Base layout', + pt: 'Layout base', + }, + file: `${baseDir}content/layout.json`, + editor: { + preview: false, + }, + fields: [ + { + name: 'header', + label: { + en: 'Header', + pt: 'Cabeçalho', + }, + widget: 'object', + fields: [ + { + name: 'pitchBar', + label: { + en: 'Pitch bar', + pt: 'Barra de anúncios', + }, + widget: 'list', + minimize_collapsed: true, + fields: [ + { + name: 'href', + label: 'Link', + required: false, + widget: 'string', + }, + { + name: 'html', + label: { + en: 'Content', + pt: 'Conteúdo', + }, + widget: 'markdown', + ...markdownOptions, + minimal: true, + }, + ], + }, + { + name: 'inlineMenuCategories', + label: { + en: 'First menu', + pt: 'Primeiro menu', + }, + widget: 'object', + fields: [ + { + name: 'featured', + label: { + en: 'Featured categories', + pt: 'Categorias em destaque', + }, + widget: 'list', + minimize_collapsed: true, + label_singular: { + en: 'category', + pt: 'categoria', + }, + }, + { + name: 'random', + label: { + en: 'Max random categories', + pt: 'Categorias aleatórias', + }, + widget: 'number', + default: 7, + value_type: 'int', + }, + ], + }, + { + name: 'isAlphabeticalSortSubmenu', + label: { + en: 'Submenu alphabetical order', + pt: 'Submenu em ordem alfabética', + }, + widget: 'boolean', + default: false, + }, + ], + }, + ], + }, + ], +}); + +export default getConfigsColl; diff --git a/packages/storefront/src/decap-cms/get-cms-config.ts b/packages/storefront/src/decap-cms/get-cms-config.ts index 94fb8dee6..990c3a957 100644 --- a/packages/storefront/src/decap-cms/get-cms-config.ts +++ b/packages/storefront/src/decap-cms/get-cms-config.ts @@ -1,7 +1,8 @@ import Deepmerge from '@fastify/deepmerge'; import { i18n as _i18n } from '@ecomplus/utils'; +import getConfigsColl from './collections/get-configs-coll'; -export const getCmsConfig = () => { +export const getCmsConfig = async () => { const { CMS_REPO_BASE_DIR, CMS_LANG, @@ -24,7 +25,21 @@ export const getCmsConfig = () => { }, }, })); - const maxFileSize = Math.max(CMS_MAX_FILE_SIZE || 0, 1000000); + const collOptions = { + domain, + baseDir, + locale, + maxFileSize: Math.max(CMS_MAX_FILE_SIZE || 0, 1000000), + markdownOptions: { + buttons: [ + 'bold', 'italic', 'link', + 'heading-three', 'heading-four', 'heading-five', + 'quote', 'bulleted-list', 'numbered-list', + ], + editor_components: ['image'], + modes: ['rich_text'], + }, + }; const config: Record = { locale, load_config_file: false, @@ -42,322 +57,7 @@ export const getCmsConfig = () => { sanitize_replacement: '-', }, collections: i18n([ - { - name: 'config', - label: { - en: 'Settings', - pt: 'Configurações', - }, - description: { - en: 'General settings for site identity and metadata', - pt: 'Configurações gerais para identidade e metadados do site', - }, - delete: false, - editor: { - preview: false, - }, - files: [ - { - name: 'settings', - label: { - en: 'General config', - pt: 'Configurações gerais', - }, - file: `${baseDir}content/settings.json`, - editor: { - preview: true, - }, - fields: [ - { - label: 'e-com.plus Store ID', - name: 'storeId', - widget: 'hidden', - }, - { - label: 'Repository', - name: 'repository', - widget: 'hidden', - }, - { - label: { - en: 'Domain name', - pt: 'Domínio', - }, - name: 'domain', - widget: 'string', - }, - { - label: { - en: 'Store name', - pt: 'Nome da loja', - }, - name: 'name', - widget: 'string', - }, - { - label: { - en: 'Short description', - pt: 'Descrição curta', - }, - name: 'description', - widget: 'text', - }, - { - label: { - en: 'Logo', - pt: 'Logomarca', - }, - name: 'logo', - widget: 'image', - media_library: { - config: { - max_file_size: maxFileSize, - }, - }, - }, - { - label: { - en: 'Icon', - pt: 'Ícone', - }, - name: 'icon', - widget: 'image', - media_library: { - config: { - max_file_size: maxFileSize, - }, - }, - }, - { - label: { - en: 'Primary color', - pt: 'Cor primária', - }, - name: 'primaryColor', - widget: 'color', - }, - { - label: { - en: 'Secondary color', - pt: 'Cor secundária', - }, - name: 'secondaryColor', - widget: 'color', - required: false, - }, - { - label: { - en: 'Contact email', - pt: 'E-mail de contato', - }, - name: 'email', - widget: 'string', - required: false, - }, - { - label: { - en: 'Service telephone', - pt: 'Telefone de atendimento', - }, - name: 'phone', - widget: 'string', - required: false, - }, - { - label: { - en: 'Store address', - pt: 'Endereço da loja', - }, - name: 'address', - widget: 'string', - required: false, - }, - { - label: { - en: 'Corporate name', - pt: 'Razão social da empresa', - }, - name: 'corporateName', - widget: 'string', - }, - { - label: { - en: 'Store document number', - pt: 'CNPJ', - }, - name: 'docNumber', - widget: 'string', - }, - { - label: { - en: 'Service links', - pt: 'Links de atendimento', - }, - name: 'serviceLinks', - widget: 'list', - summary: '{{fields.title}}', - fields: [ - { - label: { - en: 'Title', - pt: 'Título', - }, - name: 'title', - widget: 'string', - }, - { - label: 'Link', - name: 'href', - widget: 'string', - }, - ], - }, - { - label: { - en: 'Payment methods', - pt: 'Formas de pagamento', - }, - name: 'paymentMethods', - widget: 'select', - multiple: true, - options: [ - 'pix', - 'visa', - 'mastercard', - 'elo', - 'amex', - 'hipercard', - 'boleto', - 'diners', - 'discover', - ], - }, - { - label: 'WhatsApp', - name: 'whatsapp', - widget: 'string', - required: false, - }, - { - label: 'Instagram', - name: 'instagram', - widget: 'string', - required: false, - }, - { - label: 'Facebook', - name: 'facebook', - widget: 'string', - required: false, - }, - { - label: 'X / Twitter', - name: 'twitter', - widget: 'string', - required: false, - }, - { - label: 'YouTube', - name: 'youtube', - widget: 'string', - required: false, - }, - { - label: 'TikTok', - name: 'tiktok', - widget: 'string', - required: false, - }, - { - label: 'Pinterest', - name: 'pinterest', - widget: 'string', - required: false, - }, - { - label: 'Threads', - name: 'threads', - widget: 'string', - required: false, - }, - { - label: { - en: 'Default locale', - pt: 'Língua padrão', - }, - name: 'lang', - widget: 'select', - options: [ - { - label: 'Português', - value: 'pt_br', - }, - { - label: 'Inglês', - value: 'en_us', - }, - ], - default: 'pt_br', - }, - { - label: { - en: 'Currency code', - pt: 'Código da moeda', - }, - name: 'currency', - widget: 'hidden', - default: 'BRL', - }, - { - label: { - en: 'Currency symbol', - pt: 'Símbolo da moeda', - }, - name: 'currencySymbol', - widget: 'hidden', - default: 'R$', - }, - { - label: { - en: 'Country code', - pt: 'Código do país', - }, - name: 'countryCode', - widget: 'hidden', - default: 'BR', - }, - { - name: 'modules', - widget: 'hidden', - }, - { - name: 'cartUrl', - widget: 'hidden', - }, - { - name: 'checkoutUrl', - widget: 'hidden', - }, - { - name: 'accountUrl', - widget: 'hidden', - }, - { - name: 'ordersUrl', - widget: 'hidden', - }, - { - name: 'favoritesUrl', - widget: 'hidden', - }, - { - name: 'metafields', - widget: 'hidden', - }, - ], - }, - ], - }, + getConfigsColl(collOptions), ]), }; return config; diff --git a/packages/storefront/src/lib/scripts/decap-cms.ts b/packages/storefront/src/lib/scripts/decap-cms.ts index 43b51a449..7e28ab8a7 100644 --- a/packages/storefront/src/lib/scripts/decap-cms.ts +++ b/packages/storefront/src/lib/scripts/decap-cms.ts @@ -37,7 +37,7 @@ const authAndInitCms = async () => { CMS_CUSTOM_CONFIG, CMS_SSO_URL = 'https://app.e-com.plus/pages/login?api_version=2', } = window; - cmsConfig = getCmsConfig(); + cmsConfig = await getCmsConfig(); if (CMS_CUSTOM_CONFIG) { const deepmerge = Deepmerge(); cmsConfig = deepmerge(cmsConfig, CMS_CUSTOM_CONFIG); @@ -109,22 +109,21 @@ const authAndInitCms = async () => { } if (token) { sessionStorage.removeItem(storageKey); - if (!window.opener) initCmsWithPreview(); // Ref.: https://github.com/decaporg/decap-cms/blob/e93c94f1ce707719dfb7750af82b17c38b461831/packages/decap-cms-lib-auth/src/netlify-auth.js#L46 // E.g.: https://github.com/Herohtar/netlify-cms-oauth-firebase/blob/master/functions/index.js#L9-L25 - const self = window.opener || window; - setTimeout(() => { - self.postMessage('authorizing:github', cmsConfig.backend.base_url); - setTimeout(() => { - self.postMessage( - `authorization:github:success:${JSON.stringify({ - token, - provider: cmsConfig.backend.name, - })}`, - cmsConfig.backend.base_url, - ); - }, 300); - }, 500); + window.addEventListener('message', (event) => { + if (event.data === 'authorizing:github') { + setTimeout(() => { + window.postMessage( + `authorization:github:success:${JSON.stringify({ + token, + provider: cmsConfig.backend.name, + })}`, + cmsConfig.backend.base_url, + ); + }, 300); + } + }, false); return; } if (ssoToken) { @@ -143,7 +142,11 @@ const authAndInitCms = async () => { if (!import.meta.env.SSR) { (window as any).CMS_MANUAL_INIT = true; - if (window.location.pathname.startsWith('/admin/')) { + if (window.opener?.location.pathname === window.location.pathname) { + // Emulating GitHub OAuth popup + window.opener.postMessage('authorizing:github', '*'); + window.close(); + } else if (window.location.pathname.startsWith('/admin/')) { if (window.CMS) { authAndInitCms(); } else {