UNPKG

@atlaskit/editor-plugin-quick-insert

Version:

Quick insert plugin for @atlaskit/editor-core

195 lines • 7.89 kB
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics'; import { getQuickInsertMenuItemParents } from '@atlaskit/editor-common/quick-insert/get-menu-item-parents'; import { BLOCK_TEMPLATES_SECTION, DATA_AND_CHARTS_SECTION, EMBED_SECTION, MEDIA_SECTION, OTHER_SECTION, ROVO_SECTION, STRUCTURE_SECTION, TEXT_FORMATTING_SECTION } from '@atlaskit/editor-common/quick-insert/keys'; export const QUICK_INSERT_ITEMS_ANALYTICS_DELAY_MS = 10_000; const GUID_ONLY_APP_KEY_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu; const isGuidOnlyAppKey = appKey => GUID_ONLY_APP_KEY_REGEX.test(appKey); const sectionCategoryKeys = { [BLOCK_TEMPLATES_SECTION.key]: 'blockTemplates', [DATA_AND_CHARTS_SECTION.key]: 'dataAndCharts', [EMBED_SECTION.key]: 'embed', [MEDIA_SECTION.key]: 'media', [OTHER_SECTION.key]: 'other', [ROVO_SECTION.key]: 'rovo', [STRUCTURE_SECTION.key]: 'structure', [TEXT_FORMATTING_SECTION.key]: 'textFormatting' }; const legacyCategoryKeys = new Set(['admin', 'ai', 'block-templates', 'communication', 'confluence-content', 'data-and-charts', 'development', 'embed', 'external-content', 'formatting', 'media', 'navigation', 'other', 'reporting', 'skills', 'structure', 'text-formatting', 'visuals']); const isLegacyCategoryKey = category => legacyCategoryKeys.has(category); export const calculateQuickInsertItemsAttributes = ({ providedItems }) => { const emptyCategoryInformation = () => ({ internalMacroCount: 0, internalAppCount: 0, internalAppMacroMax: 0, ecosystemMacroCount: 0, ecosystemAppCount: 0, ecosystemAppMacroMax: 0, allMacroCount: 0, allAppCount: 0, allAppMacroMax: 0 }); const emptyCategoryCounts = { blockTemplates: emptyCategoryInformation(), dataAndCharts: emptyCategoryInformation(), embed: emptyCategoryInformation(), media: emptyCategoryInformation(), other: emptyCategoryInformation(), rovo: emptyCategoryInformation(), structure: emptyCategoryInformation(), textFormatting: emptyCategoryInformation() }; const emptyLegacyCategoryCounts = { admin: emptyCategoryInformation(), ai: emptyCategoryInformation(), 'block-templates': emptyCategoryInformation(), communication: emptyCategoryInformation(), 'confluence-content': emptyCategoryInformation(), 'data-and-charts': emptyCategoryInformation(), development: emptyCategoryInformation(), embed: emptyCategoryInformation(), 'external-content': emptyCategoryInformation(), formatting: emptyCategoryInformation(), media: emptyCategoryInformation(), navigation: emptyCategoryInformation(), other: emptyCategoryInformation(), reporting: emptyCategoryInformation(), skills: emptyCategoryInformation(), structure: emptyCategoryInformation(), 'text-formatting': emptyCategoryInformation(), uncategorized: emptyCategoryInformation(), visuals: emptyCategoryInformation() }; const attributes = { category: emptyCategoryCounts, legacyCategory: emptyLegacyCategoryCounts, allCategories: emptyCategoryInformation() }; const appMacroCounts = new WeakMap(); const getAppMacroCounts = category => { const existingCounts = appMacroCounts.get(category); if (existingCounts) { return existingCounts; } const counts = { all: new Map(), internal: new Map(), ecosystem: new Map() }; appMacroCounts.set(category, counts); return counts; }; const countAppMacro = (appKey, counts) => { var _counts$get; const appMacroCount = ((_counts$get = counts.get(appKey)) !== null && _counts$get !== void 0 ? _counts$get : 0) + 1; counts.set(appKey, appMacroCount); return appMacroCount; }; const countCategoryItem = (category, item) => { var _item$app; category.allMacroCount += 1; const { key: appKey = 'unknown', source } = (_item$app = item.app) !== null && _item$app !== void 0 ? _item$app : {}; const appMacroKey = isGuidOnlyAppKey(appKey) ? 'unknown' : appKey; const counts = getAppMacroCounts(category); const allAppMacroCount = countAppMacro(appMacroKey, counts.all); category.allAppCount = counts.all.size; category.allAppMacroMax = Math.max(category.allAppMacroMax, allAppMacroCount); if (source === 'internal') { category.internalMacroCount += 1; const internalAppMacroCount = countAppMacro(appMacroKey, counts.internal); category.internalAppCount = counts.internal.size; category.internalAppMacroMax = Math.max(category.internalAppMacroMax, internalAppMacroCount); } else if (source === 'ecosystem') { category.ecosystemMacroCount += 1; const ecosystemAppMacroCount = countAppMacro(appMacroKey, counts.ecosystem); category.ecosystemAppCount = counts.ecosystem.size; category.ecosystemAppMacroMax = Math.max(category.ecosystemAppMacroMax, ecosystemAppMacroCount); } }; const countItem = item => { var _item$categories, _categories$map$filte; countCategoryItem(attributes.allCategories, item); const categories = (_item$categories = item.categories) !== null && _item$categories !== void 0 ? _item$categories : []; const normalizedCategories = new Set((_categories$map$filte = categories === null || categories === void 0 ? void 0 : categories.map(category => category.trim().toLowerCase()).filter(Boolean)) !== null && _categories$map$filte !== void 0 ? _categories$map$filte : []); let hasUnknownCategory = normalizedCategories.size === 0; for (const category of normalizedCategories) { if (isLegacyCategoryKey(category)) { countCategoryItem(attributes.legacyCategory[category], item); } else { hasUnknownCategory = true; } } if (hasUnknownCategory) { countCategoryItem(attributes.legacyCategory.uncategorized, item); } for (const { key } of getQuickInsertMenuItemParents({ category: item.category, legacyCategories: item.categories, rank: 0 })) { const categoryKey = sectionCategoryKeys[key]; if (!categoryKey) { continue; } countCategoryItem(attributes.category[categoryKey], item); } }; for (const item of providedItems) { countItem(item); } return attributes; }; export const createQuickInsertItemsAnalyticsScheduler = dispatchAnalyticsEvent => { let timeoutId; let animationFrameId; let idleCallbackId; let destroyed = false; let scheduled = false; const emit = options => { if (destroyed) { return; } dispatchAnalyticsEvent({ action: ACTION.QUICK_INSERT_INFORMATION, actionSubject: ACTION_SUBJECT.QUICK_INSERT, attributes: calculateQuickInsertItemsAttributes(options), eventType: EVENT_TYPE.OPERATIONAL }); }; return { destroy: () => { destroyed = true; if (timeoutId !== undefined) { clearTimeout(timeoutId); } if (animationFrameId !== undefined && typeof window !== 'undefined') { window.cancelAnimationFrame(animationFrameId); } if (idleCallbackId !== undefined && typeof window !== 'undefined' && typeof window.cancelIdleCallback === 'function') { window.cancelIdleCallback(idleCallbackId); } }, schedule: options => { if (scheduled || destroyed) { return; } scheduled = true; timeoutId = setTimeout(() => { if (destroyed || typeof window === 'undefined') { return; } if (typeof window.requestIdleCallback === 'function') { idleCallbackId = window.requestIdleCallback(() => emit(options)); } else if (typeof window.requestAnimationFrame === 'function') { animationFrameId = window.requestAnimationFrame(() => emit(options)); } }, QUICK_INSERT_ITEMS_ANALYTICS_DELAY_MS); } }; };