@atlaskit/editor-plugin-quick-insert
Version:
Quick insert plugin for @atlaskit/editor-core
195 lines • 7.89 kB
JavaScript
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);
}
};
};