@atlaskit/help
Version:
A cross-product help component
565 lines (557 loc) • 24.2 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useNavigationContext = exports.NavigationContextProvider = exports.CtxProvider = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = _interopRequireWildcard(require("react"));
var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
var _Requests = require("../../model/Requests");
var _Help = require("../../model/Help");
var _ctx = require("../../util/hooks/ctx");
var _constants = require("../constants");
var _helpArticleContext = require("./helpArticleContext");
var _whatsNewArticleContext = require("./whatsNewArticleContext");
var _homeContext = require("./homeContext");
var _searchContext = require("./searchContext");
var _headerContext = require("./headerContext");
var _aiAgentContext = require("./aiAgentContext");
var _excluded = ["body", "relatedArticles"],
_excluded2 = ["description"];
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var DEFAULT_ARTICLE_ID = {
id: '',
type: _Help.ARTICLE_TYPE.HELP_ARTICLE
};
var _createCtx = (0, _ctx.createCtx)(),
_createCtx2 = (0, _slicedToArray2.default)(_createCtx, 2),
useNavigationContext = exports.useNavigationContext = _createCtx2[0],
CtxProvider = exports.CtxProvider = _createCtx2[1];
var getNewHistoryItem = function getNewHistoryItem(id, type, contentAri) {
var uid = Math.floor(Math.random() * Math.pow(10, 17));
var newHistoryItem = {
uid: uid,
id: id,
type: type,
state: _Requests.REQUEST_STATE.load,
contentAri: contentAri
};
return newHistoryItem;
};
/**
* Get a simplified version of the history. The items in this array should
* have only the ID, UID and state === 'reload'
*/
var getSimpleHistory = function getSimpleHistory(history) {
return history.map(function (historyItem) {
var id = historyItem.id,
uid = historyItem.uid,
type = historyItem.type,
contentAri = historyItem.contentAri;
return {
id: id,
uid: uid,
state: _Requests.REQUEST_STATE.reload,
type: type,
contentAri: contentAri
};
});
};
/**
* Get history data (list of IDs and UID)
*/
var getHistoryData = function getHistoryData(history) {
return history.map(function (historyItem) {
var id = historyItem.id,
uid = historyItem.uid,
contentAri = historyItem.contentAri;
return {
id: id,
uid: uid,
contentAri: contentAri
};
});
};
/**
* Get the last article in the history
*/
var _getCurrentArticle2 = function getCurrentArticle(history) {
return history[history.length - 1];
};
/**
* Get an ArticleItem/WhatsNewArticleItem based on the last article in the history
*/
var getCurrentArticleItemSlim = function getCurrentArticleItemSlim(history) {
var _getCurrentArticle = _getCurrentArticle2(history),
article = _getCurrentArticle.article,
type = _getCurrentArticle.type;
if (article) {
if (type === _Help.ARTICLE_TYPE.HELP_ARTICLE) {
var _ref = article,
body = _ref.body,
relatedArticles = _ref.relatedArticles,
articleItemData = (0, _objectWithoutProperties2.default)(_ref, _excluded);
var currentArticleSlimData = articleItemData;
return currentArticleSlimData;
} else if (type === _Help.ARTICLE_TYPE.WHATS_NEW) {
var _ref2 = article,
description = _ref2.description,
whatsNewArticleItemData = (0, _objectWithoutProperties2.default)(_ref2, _excluded2);
var currentWhatsNewArticleSlimData = whatsNewArticleItemData;
return currentWhatsNewArticleSlimData;
}
}
};
var getViewForArticleId = function getViewForArticleId(articleId) {
var view = _constants.VIEW.DEFAULT_CONTENT;
if (articleId.type === _Help.ARTICLE_TYPE.HELP_ARTICLE) {
if (articleId.id) {
view = _constants.VIEW.ARTICLE;
} else {
view = _constants.VIEW.DEFAULT_CONTENT;
}
} else if (articleId.type === _Help.ARTICLE_TYPE.WHATS_NEW) {
if (articleId.id) {
view = _constants.VIEW.WHATS_NEW_ARTICLE;
} else {
view = _constants.VIEW.WHATS_NEW;
}
}
return view;
};
var navigationReducer = function navigationReducer(_ref3, action) {
var currentArticleId = _ref3.articleId,
currentHistory = _ref3.history,
currentView = _ref3.view;
var newState = {
articleId: currentArticleId,
history: currentHistory,
view: currentView
};
if (action.type === 'newArticle' && action.payload) {
var newArticleId = action.payload;
if ((0, _isEqual.default)(newArticleId, DEFAULT_ARTICLE_ID)) {
newState = {
articleId: newArticleId,
history: [],
view: _constants.VIEW.DEFAULT_CONTENT
};
} else {
newState = {
articleId: newArticleId,
history: [].concat((0, _toConsumableArray2.default)(currentHistory), [getNewHistoryItem(newArticleId.id, newArticleId.type, newArticleId.contentAri)]),
view: getViewForArticleId(newArticleId)
};
}
} else if (action.type === 'addNewHistoryItem' && action.payload) {
var _newArticleId = action.payload;
newState = {
articleId: currentArticleId,
history: [].concat((0, _toConsumableArray2.default)(currentHistory), [getNewHistoryItem(_newArticleId.id, _newArticleId.type, _newArticleId.contentAri)]),
view: getViewForArticleId(currentArticleId)
};
} else if (action.type === 'updateHistoryItem' && action.payload) {
var HistoryItemUpdate = action.payload;
var index = currentHistory.findIndex(function (historyItemTemp) {
return historyItemTemp.uid === HistoryItemUpdate.uid;
});
if (index !== -1) {
var newHistory = (0, _toConsumableArray2.default)(currentHistory);
newHistory[index] = _objectSpread({}, HistoryItemUpdate);
newState = {
articleId: currentArticleId,
history: newHistory,
view: getViewForArticleId(currentArticleId)
};
}
} else if (action.type === 'removeLastHistoryItem') {
var _newHistory = currentHistory.length > 0 ? (0, _toConsumableArray2.default)(currentHistory) : [];
if (_newHistory.length > 0) {
_newHistory.splice(-1);
}
newState = {
articleId: currentArticleId,
history: _newHistory,
view: getViewForArticleId(currentArticleId)
};
} else if (action.type === 'removeAllHistoryItems') {
var defaultHistory = [];
newState = {
articleId: currentArticleId,
history: defaultHistory,
view: _constants.VIEW.DEFAULT_CONTENT
};
} else if (action.type === 'updateArticleId' && action.payload) {
var _newArticleId2 = action.payload;
newState = {
articleId: _newArticleId2,
history: currentHistory,
// If the current view is the search view and the new article id is empty, keep the current view
view: currentView === _constants.VIEW.SEARCH && _newArticleId2.id === '' ? currentView : getViewForArticleId(_newArticleId2)
};
} else if (action.type === 'updateView' && action.payload) {
var newView = action.payload;
newState = {
articleId: currentArticleId,
history: newView === _constants.VIEW.SEARCH ? [] : currentHistory,
view: newView
};
}
return newState;
};
var NavigationContextProvider = exports.NavigationContextProvider = function NavigationContextProvider(_ref4) {
var _ref4$navigationData = _ref4.navigationData,
navigationData = _ref4$navigationData === void 0 ? {
articleId: DEFAULT_ARTICLE_ID,
history: []
} : _ref4$navigationData,
setNavigationData = _ref4.setNavigationData,
children = _ref4.children;
var _useHelpArticleContex = (0, _helpArticleContext.useHelpArticleContext)(),
onGetHelpArticle = _useHelpArticleContex.onGetHelpArticle;
var _useWhatsNewArticleCo = (0, _whatsNewArticleContext.useWhatsNewArticleContext)(),
onGetWhatsNewArticle = _useWhatsNewArticleCo.onGetWhatsNewArticle;
var _useHomeContext = (0, _homeContext.useHomeContext)(),
homeContent = _useHomeContext.homeContent,
homeOptions = _useHomeContext.homeOptions;
var _useSearchContext = (0, _searchContext.useSearchContext)(),
onSearch = _useSearchContext.onSearch,
isSearchResultVisible = _useSearchContext.isSearchResultVisible,
searchValue = _useSearchContext.searchValue,
searchResult = _useSearchContext.searchResult;
var _useHeaderContext = (0, _headerContext.useHeaderContext)(),
onCloseButtonClick = _useHeaderContext.onCloseButtonClick;
var propsArticleId = navigationData.articleId,
propsHistory = navigationData.history;
var _useAiContext = (0, _aiAgentContext.useAiContext)(),
isAiEnabled = _useAiContext.isAiEnabled;
var _useReducer = (0, _react.useReducer)(navigationReducer, {
articleId: propsArticleId,
history: !(0, _isEqual.default)(propsArticleId, DEFAULT_ARTICLE_ID) && propsHistory.length === 0 ? [getNewHistoryItem(propsArticleId.id, propsArticleId.type, propsArticleId.contentAri)] : propsHistory,
view: _constants.VIEW.DEFAULT_CONTENT
}),
_useReducer2 = (0, _slicedToArray2.default)(_useReducer, 2),
_useReducer2$ = _useReducer2[0],
currentArticleId = _useReducer2$.articleId,
currentHistory = _useReducer2$.history,
currentView = _useReducer2$.view,
dispatchNavigationAction = _useReducer2[1];
var isOverlayVisible = (0, _react.useMemo)(function () {
return currentView === _constants.VIEW.ARTICLE || currentView === _constants.VIEW.SEARCH || currentView === _constants.VIEW.WHATS_NEW || currentView === _constants.VIEW.WHATS_NEW_ARTICLE;
}, [currentView]);
var isDefaultContentDefined = (0, _react.useMemo)(function () {
return homeContent !== undefined || homeOptions !== undefined;
}, [homeContent, homeOptions]);
var canNavigateBack = (0, _react.useMemo)(function () {
/**
* - If default content isn't defined and the history only has one article,
* we should not display the back button
*/
if (currentHistory.length === 1 && !isDefaultContentDefined || currentView === _constants.VIEW.WHATS_NEW && !isDefaultContentDefined || isAiEnabled && currentView === _constants.VIEW.SEARCH) {
return false;
}
/**
* if an overlay is visible return true to display the back buton
*/
return isOverlayVisible;
}, [currentHistory.length, isDefaultContentDefined, isOverlayVisible, currentView, isAiEnabled]);
var fetchArticleData = (0, _react.useCallback)( /*#__PURE__*/function () {
var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(historyItem) {
var article;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
_context.prev = 0;
_context.t0 = historyItem.type;
_context.next = _context.t0 === _Help.ARTICLE_TYPE.HELP_ARTICLE ? 4 : _context.t0 === _Help.ARTICLE_TYPE.WHATS_NEW ? 10 : 18;
break;
case 4:
if (onGetHelpArticle) {
_context.next = 6;
break;
}
throw new Error('onGetHelpArticle prop not defined');
case 6:
_context.next = 8;
return onGetHelpArticle({
id: historyItem.id,
type: historyItem.type,
contentAri: historyItem.contentAri
});
case 8:
article = _context.sent;
return _context.abrupt("break", 19);
case 10:
if (onGetWhatsNewArticle) {
_context.next = 12;
break;
}
throw new Error('onGetWhatsNewArticle prop not defined');
case 12:
if (!(historyItem.id === '')) {
_context.next = 14;
break;
}
return _context.abrupt("break", 19);
case 14:
_context.next = 16;
return onGetWhatsNewArticle({
id: historyItem.id,
type: historyItem.type
});
case 16:
article = _context.sent;
return _context.abrupt("break", 19);
case 18:
throw new Error('onGetHelpArticle prop not defined');
case 19:
return _context.abrupt("return", _objectSpread(_objectSpread(_objectSpread({}, historyItem), article && {
article: article
}), {}, {
state: _Requests.REQUEST_STATE.done
}));
case 22:
_context.prev = 22;
_context.t1 = _context["catch"](0);
return _context.abrupt("return", _objectSpread(_objectSpread({}, historyItem), {}, {
state: _Requests.REQUEST_STATE.error
}));
case 25:
case "end":
return _context.stop();
}
}, _callee, null, [[0, 22]]);
}));
return function (_x) {
return _ref5.apply(this, arguments);
};
}(), [onGetHelpArticle, onGetWhatsNewArticle]);
var reloadArticle = (0, _react.useCallback)( /*#__PURE__*/function () {
var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(historyItem) {
var historyItemToReload;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
historyItemToReload = _objectSpread({}, historyItem);
if (historyItem.type === _Help.ARTICLE_TYPE.HELP_ARTICLE || historyItem.type === _Help.ARTICLE_TYPE.WHATS_NEW) {
historyItemToReload.state = _Requests.REQUEST_STATE.loading;
} else {
historyItemToReload.state = _Requests.REQUEST_STATE.error;
}
dispatchNavigationAction({
type: 'updateHistoryItem',
payload: historyItemToReload
});
case 3:
case "end":
return _context2.stop();
}
}, _callee2);
}));
return function (_x2) {
return _ref6.apply(this, arguments);
};
}(), []);
var navigateBack = (0, _react.useCallback)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
var _searchResult$length;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) switch (_context3.prev = _context3.next) {
case 0:
if (!(currentView === _constants.VIEW.SEARCH && onSearch)) {
_context3.next = 8;
break;
}
if (!(searchValue !== '')) {
_context3.next = 6;
break;
}
onSearch('');
return _context3.abrupt("return");
case 6:
dispatchNavigationAction({
type: 'updateView',
payload: currentArticleId.type
});
return _context3.abrupt("return");
case 8:
// if the history is not empty and ...
if (currentHistory.length > 0) {
// the history has more than one article, navigate back through the history
if (currentHistory.length > 1) {
// Remove last element
dispatchNavigationAction({
type: 'removeLastHistoryItem'
});
} else if (currentHistory.length === 1) {
// If the search value is not empty and search result is not empty, show the search results
if (searchValue !== '' && ((_searchResult$length = searchResult === null || searchResult === void 0 ? void 0 : searchResult.length) !== null && _searchResult$length !== void 0 ? _searchResult$length : 0) > 0 && onSearch !== undefined) {
dispatchNavigationAction({
type: 'updateView',
payload: _constants.VIEW.SEARCH
});
}
// If the search value is empty, show the default content
else {
dispatchNavigationAction({
type: 'removeAllHistoryItems'
});
}
}
}
case 9:
case "end":
return _context3.stop();
}
}, _callee3);
})), [currentView, searchValue, currentArticleId, currentHistory, onSearch, searchResult === null || searchResult === void 0 ? void 0 : searchResult.length]);
var onClose = (0, _react.useCallback)(function (event, analyticsEvent) {
if (onCloseButtonClick) {
dispatchNavigationAction({
type: 'removeAllHistoryItems'
});
onCloseButtonClick(event, analyticsEvent);
}
}, [onCloseButtonClick]);
var onOpenArticle = (0, _react.useCallback)(function (newArticleId) {
dispatchNavigationAction({
type: 'addNewHistoryItem',
payload: newArticleId
});
}, []);
(0, _react.useEffect)(function () {
// If the search result is visible or the search value is not empty, show the search result
if (isSearchResultVisible || searchValue !== '') {
dispatchNavigationAction({
type: 'updateView',
payload: _constants.VIEW.SEARCH
});
// If the search result is not visible and the search value is empty, show the default content
} else if (!isSearchResultVisible && searchValue === '') {
dispatchNavigationAction({
type: 'updateView',
payload: _constants.VIEW.DEFAULT_CONTENT
});
}
}, [isSearchResultVisible, searchValue]);
(0, _react.useEffect)(function () {
var lastHistoryItem = currentHistory.length > 0 ? _getCurrentArticle2(currentHistory) : getNewHistoryItem(DEFAULT_ARTICLE_ID.id, DEFAULT_ARTICLE_ID.type);
/**
* If the propsArticleId.id (host articleId) is different from currentArticleId.id (internal articleId)
* */
if (!(0, _isEqual.default)(propsArticleId, currentArticleId)) {
/**
* If propsArticleId and lastHistoryItem are the same, we just need to update the articleId
* because is out of sync
*/
if (propsArticleId.id === lastHistoryItem.id && propsArticleId.type === lastHistoryItem.type) {
dispatchNavigationAction({
type: 'updateArticleId',
payload: propsArticleId
});
} else {
/**
* Otherwise we need to add a new article
*/
dispatchNavigationAction({
type: 'newArticle',
payload: propsArticleId
});
}
} else {
if (setNavigationData) {
var simpleHistory = getSimpleHistory(currentHistory);
if (currentArticleId.id !== lastHistoryItem.id || currentArticleId.type !== lastHistoryItem.type) {
/**
* If the propsArticleId.id (host articleId) is equal to currentArticleId.id (internal articleId)
* and the id from the last history item is different from currentArticleId.id, it means the history
* changed
* */
if (setNavigationData) {
setNavigationData({
articleId: {
id: lastHistoryItem.id,
type: lastHistoryItem.type,
contentAri: lastHistoryItem.contentAri
},
history: simpleHistory
});
}
} else if (!(0, _isEqual.default)(getHistoryData(propsHistory), getHistoryData(currentHistory))) {
setNavigationData({
articleId: propsArticleId,
history: simpleHistory
});
}
}
}
}, [currentArticleId, propsArticleId, currentHistory, setNavigationData, propsHistory]);
(0, _react.useEffect)(function () {
var requestNewArticle = /*#__PURE__*/function () {
var _ref8 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(historyItem) {
var historyItemUpdate;
return _regenerator.default.wrap(function _callee4$(_context4) {
while (1) switch (_context4.prev = _context4.next) {
case 0:
_context4.next = 2;
return fetchArticleData(historyItem);
case 2:
historyItemUpdate = _context4.sent;
dispatchNavigationAction({
type: 'updateHistoryItem',
payload: historyItemUpdate
});
case 4:
case "end":
return _context4.stop();
}
}, _callee4);
}));
return function requestNewArticle(_x3) {
return _ref8.apply(this, arguments);
};
}();
/**
* If the last history item state is "loading" or "reload", we need to request the article (fetch article from API)
*/
var lastHistoryItem = _getCurrentArticle2(currentHistory);
if ((lastHistoryItem === null || lastHistoryItem === void 0 ? void 0 : lastHistoryItem.state) === _Requests.REQUEST_STATE.load || (lastHistoryItem === null || lastHistoryItem === void 0 ? void 0 : lastHistoryItem.state) === _Requests.REQUEST_STATE.reload) {
requestNewArticle(lastHistoryItem);
dispatchNavigationAction({
type: 'updateHistoryItem',
payload: _objectSpread(_objectSpread({}, lastHistoryItem), {}, {
state: _Requests.REQUEST_STATE.loading
})
});
}
}, [currentArticleId, currentHistory, fetchArticleData]);
return /*#__PURE__*/_react.default.createElement(CtxProvider, {
value: {
view: currentView,
articleId: currentArticleId,
openArticle: onOpenArticle,
history: currentHistory,
getCurrentArticle: function getCurrentArticle() {
return _getCurrentArticle2(currentHistory);
},
getCurrentArticleItemData: function getCurrentArticleItemData() {
return getCurrentArticleItemSlim(currentHistory);
},
reloadHelpArticle: onGetHelpArticle && reloadArticle,
reloadWhatsNewArticle: onGetWhatsNewArticle && reloadArticle,
canNavigateBack: canNavigateBack,
navigateBack: navigateBack,
isOverlayVisible: isOverlayVisible,
onClose: onClose
}
}, children);
};