strapi-plugin-meilisearch
Version:
Synchronise and search in your Strapi content-types with Meilisearch
1,004 lines (1,003 loc) • 39.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxRuntime = require("react/jsx-runtime");
const React = require("react");
const reactRouterDom = require("react-router-dom");
const admin = require("@strapi/strapi/admin");
const index = require("./index-OgM-GMGo.js");
const designSystem = require("@strapi/design-system");
function _interopNamespace(e) {
if (e && e.__esModule) return e;
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
if (e) {
for (const k in e) {
if (k !== "default") {
const d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: () => e[k]
});
}
}
}
n.default = e;
return Object.freeze(n);
}
const React__namespace = /* @__PURE__ */ _interopNamespace(React);
var __assign = function() {
__assign = Object.assign || function __assign2(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
var reactIs$1 = { exports: {} };
var reactIs_production_min = {};
/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var hasRequiredReactIs_production_min;
function requireReactIs_production_min() {
if (hasRequiredReactIs_production_min) return reactIs_production_min;
hasRequiredReactIs_production_min = 1;
var b = "function" === typeof Symbol && Symbol.for, c = b ? Symbol.for("react.element") : 60103, d = b ? Symbol.for("react.portal") : 60106, e = b ? Symbol.for("react.fragment") : 60107, f = b ? Symbol.for("react.strict_mode") : 60108, g = b ? Symbol.for("react.profiler") : 60114, h = b ? Symbol.for("react.provider") : 60109, k = b ? Symbol.for("react.context") : 60110, l = b ? Symbol.for("react.async_mode") : 60111, m = b ? Symbol.for("react.concurrent_mode") : 60111, n = b ? Symbol.for("react.forward_ref") : 60112, p = b ? Symbol.for("react.suspense") : 60113, q = b ? Symbol.for("react.suspense_list") : 60120, r = b ? Symbol.for("react.memo") : 60115, t = b ? Symbol.for("react.lazy") : 60116, v = b ? Symbol.for("react.block") : 60121, w = b ? Symbol.for("react.fundamental") : 60117, x = b ? Symbol.for("react.responder") : 60118, y = b ? Symbol.for("react.scope") : 60119;
function z(a) {
if ("object" === typeof a && null !== a) {
var u = a.$$typeof;
switch (u) {
case c:
switch (a = a.type, a) {
case l:
case m:
case e:
case g:
case f:
case p:
return a;
default:
switch (a = a && a.$$typeof, a) {
case k:
case n:
case t:
case r:
case h:
return a;
default:
return u;
}
}
case d:
return u;
}
}
}
function A(a) {
return z(a) === m;
}
reactIs_production_min.AsyncMode = l;
reactIs_production_min.ConcurrentMode = m;
reactIs_production_min.ContextConsumer = k;
reactIs_production_min.ContextProvider = h;
reactIs_production_min.Element = c;
reactIs_production_min.ForwardRef = n;
reactIs_production_min.Fragment = e;
reactIs_production_min.Lazy = t;
reactIs_production_min.Memo = r;
reactIs_production_min.Portal = d;
reactIs_production_min.Profiler = g;
reactIs_production_min.StrictMode = f;
reactIs_production_min.Suspense = p;
reactIs_production_min.isAsyncMode = function(a) {
return A(a) || z(a) === l;
};
reactIs_production_min.isConcurrentMode = A;
reactIs_production_min.isContextConsumer = function(a) {
return z(a) === k;
};
reactIs_production_min.isContextProvider = function(a) {
return z(a) === h;
};
reactIs_production_min.isElement = function(a) {
return "object" === typeof a && null !== a && a.$$typeof === c;
};
reactIs_production_min.isForwardRef = function(a) {
return z(a) === n;
};
reactIs_production_min.isFragment = function(a) {
return z(a) === e;
};
reactIs_production_min.isLazy = function(a) {
return z(a) === t;
};
reactIs_production_min.isMemo = function(a) {
return z(a) === r;
};
reactIs_production_min.isPortal = function(a) {
return z(a) === d;
};
reactIs_production_min.isProfiler = function(a) {
return z(a) === g;
};
reactIs_production_min.isStrictMode = function(a) {
return z(a) === f;
};
reactIs_production_min.isSuspense = function(a) {
return z(a) === p;
};
reactIs_production_min.isValidElementType = function(a) {
return "string" === typeof a || "function" === typeof a || a === e || a === m || a === g || a === f || a === p || a === q || "object" === typeof a && null !== a && (a.$$typeof === t || a.$$typeof === r || a.$$typeof === h || a.$$typeof === k || a.$$typeof === n || a.$$typeof === w || a.$$typeof === x || a.$$typeof === y || a.$$typeof === v);
};
reactIs_production_min.typeOf = z;
return reactIs_production_min;
}
var reactIs_development = {};
/** @license React v16.13.1
* react-is.development.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var hasRequiredReactIs_development;
function requireReactIs_development() {
if (hasRequiredReactIs_development) return reactIs_development;
hasRequiredReactIs_development = 1;
if (process.env.NODE_ENV !== "production") {
(function() {
var hasSymbol = typeof Symbol === "function" && Symbol.for;
var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 60103;
var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 60106;
var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for("react.fragment") : 60107;
var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for("react.strict_mode") : 60108;
var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 60114;
var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 60109;
var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 60110;
var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for("react.async_mode") : 60111;
var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for("react.concurrent_mode") : 60111;
var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 60112;
var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 60113;
var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for("react.suspense_list") : 60120;
var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115;
var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116;
var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 60121;
var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for("react.fundamental") : 60117;
var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for("react.responder") : 60118;
var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for("react.scope") : 60119;
function isValidElementType(type) {
return typeof type === "string" || typeof type === "function" || // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill.
type === REACT_FRAGMENT_TYPE || type === REACT_CONCURRENT_MODE_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || typeof type === "object" && type !== null && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_RESPONDER_TYPE || type.$$typeof === REACT_SCOPE_TYPE || type.$$typeof === REACT_BLOCK_TYPE);
}
function typeOf(object) {
if (typeof object === "object" && object !== null) {
var $$typeof = object.$$typeof;
switch ($$typeof) {
case REACT_ELEMENT_TYPE:
var type = object.type;
switch (type) {
case REACT_ASYNC_MODE_TYPE:
case REACT_CONCURRENT_MODE_TYPE:
case REACT_FRAGMENT_TYPE:
case REACT_PROFILER_TYPE:
case REACT_STRICT_MODE_TYPE:
case REACT_SUSPENSE_TYPE:
return type;
default:
var $$typeofType = type && type.$$typeof;
switch ($$typeofType) {
case REACT_CONTEXT_TYPE:
case REACT_FORWARD_REF_TYPE:
case REACT_LAZY_TYPE:
case REACT_MEMO_TYPE:
case REACT_PROVIDER_TYPE:
return $$typeofType;
default:
return $$typeof;
}
}
case REACT_PORTAL_TYPE:
return $$typeof;
}
}
return void 0;
}
var AsyncMode = REACT_ASYNC_MODE_TYPE;
var ConcurrentMode = REACT_CONCURRENT_MODE_TYPE;
var ContextConsumer = REACT_CONTEXT_TYPE;
var ContextProvider = REACT_PROVIDER_TYPE;
var Element = REACT_ELEMENT_TYPE;
var ForwardRef = REACT_FORWARD_REF_TYPE;
var Fragment = REACT_FRAGMENT_TYPE;
var Lazy = REACT_LAZY_TYPE;
var Memo = REACT_MEMO_TYPE;
var Portal = REACT_PORTAL_TYPE;
var Profiler = REACT_PROFILER_TYPE;
var StrictMode = REACT_STRICT_MODE_TYPE;
var Suspense = REACT_SUSPENSE_TYPE;
var hasWarnedAboutDeprecatedIsAsyncMode = false;
function isAsyncMode(object) {
{
if (!hasWarnedAboutDeprecatedIsAsyncMode) {
hasWarnedAboutDeprecatedIsAsyncMode = true;
console["warn"]("The ReactIs.isAsyncMode() alias has been deprecated, and will be removed in React 17+. Update your code to use ReactIs.isConcurrentMode() instead. It has the exact same API.");
}
}
return isConcurrentMode(object) || typeOf(object) === REACT_ASYNC_MODE_TYPE;
}
function isConcurrentMode(object) {
return typeOf(object) === REACT_CONCURRENT_MODE_TYPE;
}
function isContextConsumer(object) {
return typeOf(object) === REACT_CONTEXT_TYPE;
}
function isContextProvider(object) {
return typeOf(object) === REACT_PROVIDER_TYPE;
}
function isElement(object) {
return typeof object === "object" && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
}
function isForwardRef(object) {
return typeOf(object) === REACT_FORWARD_REF_TYPE;
}
function isFragment(object) {
return typeOf(object) === REACT_FRAGMENT_TYPE;
}
function isLazy(object) {
return typeOf(object) === REACT_LAZY_TYPE;
}
function isMemo(object) {
return typeOf(object) === REACT_MEMO_TYPE;
}
function isPortal(object) {
return typeOf(object) === REACT_PORTAL_TYPE;
}
function isProfiler(object) {
return typeOf(object) === REACT_PROFILER_TYPE;
}
function isStrictMode(object) {
return typeOf(object) === REACT_STRICT_MODE_TYPE;
}
function isSuspense(object) {
return typeOf(object) === REACT_SUSPENSE_TYPE;
}
reactIs_development.AsyncMode = AsyncMode;
reactIs_development.ConcurrentMode = ConcurrentMode;
reactIs_development.ContextConsumer = ContextConsumer;
reactIs_development.ContextProvider = ContextProvider;
reactIs_development.Element = Element;
reactIs_development.ForwardRef = ForwardRef;
reactIs_development.Fragment = Fragment;
reactIs_development.Lazy = Lazy;
reactIs_development.Memo = Memo;
reactIs_development.Portal = Portal;
reactIs_development.Profiler = Profiler;
reactIs_development.StrictMode = StrictMode;
reactIs_development.Suspense = Suspense;
reactIs_development.isAsyncMode = isAsyncMode;
reactIs_development.isConcurrentMode = isConcurrentMode;
reactIs_development.isContextConsumer = isContextConsumer;
reactIs_development.isContextProvider = isContextProvider;
reactIs_development.isElement = isElement;
reactIs_development.isForwardRef = isForwardRef;
reactIs_development.isFragment = isFragment;
reactIs_development.isLazy = isLazy;
reactIs_development.isMemo = isMemo;
reactIs_development.isPortal = isPortal;
reactIs_development.isProfiler = isProfiler;
reactIs_development.isStrictMode = isStrictMode;
reactIs_development.isSuspense = isSuspense;
reactIs_development.isValidElementType = isValidElementType;
reactIs_development.typeOf = typeOf;
})();
}
return reactIs_development;
}
if (process.env.NODE_ENV === "production") {
reactIs$1.exports = requireReactIs_production_min();
} else {
reactIs$1.exports = requireReactIs_development();
}
var reactIsExports = reactIs$1.exports;
var reactIs = reactIsExports;
var FORWARD_REF_STATICS = {
"$$typeof": true,
render: true,
defaultProps: true,
displayName: true,
propTypes: true
};
var MEMO_STATICS = {
"$$typeof": true,
compare: true,
defaultProps: true,
displayName: true,
propTypes: true,
type: true
};
var TYPE_STATICS = {};
TYPE_STATICS[reactIs.ForwardRef] = FORWARD_REF_STATICS;
TYPE_STATICS[reactIs.Memo] = MEMO_STATICS;
function invariant(condition, message, Err) {
if (Err === void 0) {
Err = Error;
}
if (!condition) {
throw new Err(message);
}
}
var defaultErrorHandler = function(error) {
if (process.env.NODE_ENV !== "production") {
console.error(error);
}
};
var defaultWarnHandler = function(warning) {
if (process.env.NODE_ENV !== "production") {
console.warn(warning);
}
};
var DEFAULT_INTL_CONFIG = {
formats: {},
messages: {},
timeZone: void 0,
defaultLocale: "en",
defaultFormats: {},
fallbackOnEmptyString: true,
onError: defaultErrorHandler,
onWarn: defaultWarnHandler
};
function invariantIntlContext(intl) {
invariant(intl, "[React Intl] Could not find required `intl` object. <IntlProvider> needs to exist in the component ancestry.");
}
__assign(__assign({}, DEFAULT_INTL_CONFIG), { textComponent: React__namespace.Fragment });
var IntlContext = typeof window !== "undefined" && !window.__REACT_INTL_BYPASS_GLOBAL_CONTEXT__ ? window.__REACT_INTL_CONTEXT__ || (window.__REACT_INTL_CONTEXT__ = React__namespace.createContext(null)) : React__namespace.createContext(null);
IntlContext.Consumer;
IntlContext.Provider;
var Context = IntlContext;
function useIntl() {
var intl = React__namespace.useContext(Context);
invariantIntlContext(intl);
return intl;
}
var DisplayName;
(function(DisplayName2) {
DisplayName2["formatDate"] = "FormattedDate";
DisplayName2["formatTime"] = "FormattedTime";
DisplayName2["formatNumber"] = "FormattedNumber";
DisplayName2["formatList"] = "FormattedList";
DisplayName2["formatDisplayName"] = "FormattedDisplayName";
})(DisplayName || (DisplayName = {}));
var DisplayNameParts;
(function(DisplayNameParts2) {
DisplayNameParts2["formatDate"] = "FormattedDateParts";
DisplayNameParts2["formatTime"] = "FormattedTimeParts";
DisplayNameParts2["formatNumber"] = "FormattedNumberParts";
DisplayNameParts2["formatList"] = "FormattedListParts";
})(DisplayNameParts || (DisplayNameParts = {}));
function createFormattedDateTimePartsComponent(name) {
var ComponentParts = function(props) {
var intl = useIntl();
var value = props.value, children = props.children, formatProps = __rest(props, ["value", "children"]);
var date = typeof value === "string" ? new Date(value || 0) : value;
var formattedParts = name === "formatDate" ? intl.formatDateToParts(date, formatProps) : intl.formatTimeToParts(date, formatProps);
return children(formattedParts);
};
ComponentParts.displayName = DisplayNameParts[name];
return ComponentParts;
}
function createFormattedComponent(name) {
var Component = function(props) {
var intl = useIntl();
var value = props.value, children = props.children, formatProps = __rest(
props,
["value", "children"]
);
var formattedValue = intl[name](value, formatProps);
if (typeof children === "function") {
return children(formattedValue);
}
var Text = intl.textComponent || React__namespace.Fragment;
return React__namespace.createElement(Text, null, formattedValue);
};
Component.displayName = DisplayName[name];
return Component;
}
createFormattedComponent("formatDate");
createFormattedComponent("formatTime");
createFormattedComponent("formatNumber");
createFormattedComponent("formatList");
createFormattedComponent("formatDisplayName");
createFormattedDateTimePartsComponent("formatDate");
createFormattedDateTimePartsComponent("formatTime");
const useI18n = () => {
const { formatMessage } = useIntl();
const i18n = (key, defaultMessage) => {
return formatMessage({
id: `${index.pluginId}.${key}`,
defaultMessage
});
};
return {
i18n
};
};
function useAlert() {
const { toggleNotification } = admin.useNotification();
const { i18n } = useI18n();
function handleNotification({
type = "info",
message = i18n(
"plugin.message.something",
"Something occurred in Meilisearch"
),
link,
blockTransition = true,
title
}) {
toggleNotification({
// optional
title,
// required
// type: 'info|success|warning',
type,
// required
message: i18n("notification.meilisearch.message", message),
// optional
link,
// optional: default = false
blockTransition,
// optional
onClose: () => localStorage.setItem("STRAPI_UPDATE_NOTIF", "true")
});
}
const checkForbiddenError = ({ response }) => {
const status = response?.data?.error?.status;
if (status && status === 403) {
handleNotification({
title: i18n("plugin.message.forbidden.title", "Forbidden"),
type: "warning",
message: i18n(
"plugin.message.forbidden.description",
"You do not have permission to do this action"
),
blockTransition: false
});
}
};
return {
handleNotification,
checkForbiddenError
};
}
function useCollection() {
const [collections, setCollections] = React.useState([]);
const [refetchIndex, setRefetchIndex] = React.useState(true);
const [reloadNeeded, setReloadNeeded] = React.useState(false);
const [realTimeReports, setRealTimeReports] = React.useState(false);
const { handleNotification, checkForbiddenError } = useAlert();
const { i18n } = useI18n();
const { get, del, post, put } = admin.useFetchClient();
const refetchCollection = () => setRefetchIndex((prevRefetchIndex) => !prevRefetchIndex);
const hookingTextRendering = ({ indexed, listened }) => {
if (indexed && listened)
return i18n("plugin.table.td.hookingText.hooked", "Hooked");
if (!indexed && !listened) return "/";
return i18n("plugin.table.td.hookingText.reload", "Reload needed");
};
const fetchCollections = async () => {
try {
const {
data: { data, error }
} = await get(`/${index.pluginId}/content-type/`);
if (error) {
handleNotification({
type: "warning",
message: error.message,
link: error.link
});
} else {
const collections2 = data.contentTypes.map((collection) => {
collection["reloadNeeded"] = hookingTextRendering({
indexed: collection.indexed,
listened: collection.listened
});
return collection;
});
const reload = collections2.find(
(col) => col.reloadNeeded === i18n("plugin.table.td.hookingText.reload", "Reload needed")
);
const isIndexing = collections2.find((col) => col.isIndexing === true);
if (!isIndexing) setRealTimeReports(false);
else setRealTimeReports(true);
if (reload) {
setReloadNeeded(true);
} else setReloadNeeded(false);
setCollections(collections2);
}
} catch (error) {
checkForbiddenError(error);
}
};
const deleteCollection = async ({ contentType }) => {
try {
const {
data: { error }
} = await del(`/${index.pluginId}/content-type/${contentType}`);
if (error) {
handleNotification({
type: "warning",
message: error.message,
link: error.link
});
} else {
refetchCollection();
handleNotification({
type: "success",
message: i18n(
"plugin.message.success.delete",
"Request to delete content-type is successful"
),
blockTransition: false
});
}
} catch (error) {
checkForbiddenError(error);
}
};
const addCollection = async ({ contentType }) => {
try {
const {
data: { error }
} = await post(`/${index.pluginId}/content-type`, {
contentType
});
console.log(error);
if (error) {
handleNotification({
type: "warning",
message: error.message,
link: error.link
});
} else {
refetchCollection();
handleNotification({
type: "success",
message: i18n(
"plugin.message.success.add",
"Request to add a content-type is successful"
),
blockTransition: false
});
}
} catch (error) {
checkForbiddenError(error);
}
};
const updateCollection = async ({ contentType }) => {
try {
const {
data: { error }
} = await put(`/${index.pluginId}/content-type`, {
contentType
});
if (error) {
handleNotification({
type: "warning",
message: error.message,
link: error.link
});
} else {
refetchCollection();
handleNotification({
type: "success",
message: i18n(
"plugin.message.success.update",
"Request to update content-type is successful"
),
blockTransition: false
});
}
} catch (error) {
checkForbiddenError(error);
}
};
React.useEffect(() => {
fetchCollections();
}, [refetchIndex]);
React.useEffect(() => {
let interval;
if (realTimeReports) {
interval = setInterval(() => {
refetchCollection();
}, 1e3);
} else {
clearInterval(interval);
}
return () => clearInterval(interval);
}, [realTimeReports]);
return {
collections,
deleteCollection,
addCollection,
updateCollection,
reloadNeeded,
refetchCollection,
handleNotification
};
}
const CollectionColumn = ({
entry,
deleteCollection,
addCollection,
updateCollection
}) => {
const { i18n } = useI18n();
const {
allowedActions: { canCreate, canUpdate, canDelete }
} = admin.useRBAC(index.PERMISSIONS.collections);
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
(canCreate || canDelete) && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
designSystem.Checkbox,
{
"aria-label": `Select ${entry.collection}`,
onCheckedChange: () => {
if (entry.indexed)
deleteCollection({ contentType: entry.contentType });
else addCollection({ contentType: entry.contentType });
},
checked: entry.indexed
}
) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: entry.collection }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: entry.indexed ? i18n("plugin.table.td.yes", "Yes") : i18n("plugin.table.td.no", "No") }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: entry.isIndexing ? i18n("plugin.table.td.yes", "Yes") : i18n("plugin.table.td.no", "No") }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: entry.indexUid }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { textColor: "neutral800", children: [
entry.numberOfDocuments,
" / ",
entry.numberOfEntries
] }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: entry.reloadNeeded }) }),
canUpdate && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingLeft: 1, children: entry.indexed && /* @__PURE__ */ jsxRuntime.jsx(
designSystem.Button,
{
onClick: () => updateCollection({ contentType: entry.contentType }),
size: "S",
variant: "secondary",
children: i18n("plugin.update", "Update")
}
) }) }) })
] }, entry.contentType);
};
const CollectionColumn$1 = React.memo(CollectionColumn);
const CollectionTableHeader = () => {
const { i18n } = useI18n();
const {
allowedActions: { canCreate, canUpdate, canDelete }
} = admin.useRBAC(index.PERMISSIONS.collections);
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
(canCreate || canDelete) && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { children: "INDEX" }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: i18n("plugin.table.header.name", "NAME") }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: i18n("plugin.table.header.in-meilisearch", "IN MEILISEARCH ?") }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: i18n("plugin.table.header.indexing", "INDEXING ?") }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: i18n("plugin.table.header.index-name", "INDEX NAME") }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: i18n("plugin.table.header.documents", "DOCUMENTS") }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: i18n("plugin.table.header.hooks", "HOOKS") }) }),
canUpdate && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { children: "Actions" }) })
] }) });
};
const CollectionTableHeader$1 = React.memo(CollectionTableHeader);
const SERVER_HAS_NOT_BEEN_KILLED_MESSAGE = "did-not-kill-server";
const SERVER_HAS_BEEN_KILLED_MESSAGE = "server is down";
function serverRestartWatcher(response, didShutDownServer) {
return new Promise((resolve) => {
fetch(`${window.strapi.backendURL}/_health`, {
method: "HEAD",
mode: "no-cors",
headers: {
"Content-Type": "application/json",
"Keep-Alive": "false"
}
}).then((res) => {
if (res.status >= 400) {
throw new Error(SERVER_HAS_BEEN_KILLED_MESSAGE);
}
if (!didShutDownServer) {
throw new Error(SERVER_HAS_NOT_BEEN_KILLED_MESSAGE);
}
resolve(response);
}).catch((err) => {
setTimeout(() => {
return serverRestartWatcher(
response,
err.message !== SERVER_HAS_NOT_BEEN_KILLED_MESSAGE
).then(resolve);
}, 100);
});
});
}
const Collection = () => {
const {
collections,
deleteCollection,
addCollection,
updateCollection,
reloadNeeded,
refetchCollection
} = useCollection();
const { lockAppWithAutoreload, unlockAppWithAutoreload } = admin.private_useAutoReloadOverlayBlocker();
const { get } = admin.useFetchClient();
const [reload, setReload] = React.useState(false);
const { i18n } = useI18n();
const ROW_COUNT = 6;
const COL_COUNT = 10;
const reloadServer = async () => {
try {
lockAppWithAutoreload();
await get(`/${index.pluginId}/reload`, true);
await serverRestartWatcher(true);
setReload(false);
} catch (err) {
console.error(err);
} finally {
unlockAppWithAutoreload();
refetchCollection();
}
};
React.useEffect(() => {
if (reload) reloadServer();
}, [reload]);
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { background: "neutral100", children: [
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { colCount: COL_COUNT, rowCount: ROW_COUNT, children: [
/* @__PURE__ */ jsxRuntime.jsx(CollectionTableHeader$1, {}),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: collections.map((collection) => /* @__PURE__ */ jsxRuntime.jsx(
CollectionColumn$1,
{
entry: collection,
deleteCollection,
addCollection,
updateCollection
},
collection.collection
)) })
] }),
reloadNeeded && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 5, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: () => setReload(true), children: i18n("plugin.reload-server", "Reload server") }) })
] });
};
const CollectionTable = React.memo(Collection);
function useCredential() {
const [credentials, setCredentials] = React.useState({
host: "",
apiKey: "",
ApiKeyIsFromConfigFile: true,
HostIsFromConfigFile: true
});
const [refetchIndex, setRefetchIndex] = React.useState(true);
const [host, setHost] = React.useState("");
const [apiKey, setApiKey] = React.useState("");
const { handleNotification } = useAlert();
const { i18n } = useI18n();
const { get, post } = admin.useFetchClient();
const refetchCredentials = () => setRefetchIndex((prevRefetchIndex) => !prevRefetchIndex);
const updateCredentials = async () => {
const {
data: { error }
} = await post(`/${index.pluginId}/credential`, {
apiKey,
host
});
if (error) {
handleNotification({
type: "warning",
message: error.message,
link: error.link
});
} else {
refetchCredentials();
handleNotification({
type: "success",
message: i18n(
"plugin.message.success.credentials",
"Credentials sucessfully updated!"
),
blockTransition: false
});
}
};
const fetchCredentials = async () => {
const {
data: { data, error }
} = await get(`/${index.pluginId}/credential`);
if (error) {
handleNotification({
type: "warning",
message: error.message,
link: error.link
});
} else {
setCredentials(data);
setHost(data.host);
setApiKey(data.apiKey);
}
};
React.useEffect(() => {
fetchCredentials();
}, [refetchIndex]);
return {
credentials,
updateCredentials,
setHost,
setApiKey,
host,
apiKey
};
}
const Credentials = () => {
const { host, apiKey, credentials, setHost, setApiKey, updateCredentials } = useCredential();
const { i18n } = useI18n();
const {
allowedActions: { canEdit }
} = admin.useRBAC(index.PERMISSIONS.settingsEdit);
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(
designSystem.Field.Root,
{
id: "host",
hint: i18n(
"plugin.tab.settings.input.url.hint",
"The URL on which your Meilisearch is running"
),
children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: i18n("plugin.tab.settings.input.url.label", "Meilisearch URL") }),
/* @__PURE__ */ jsxRuntime.jsx(
designSystem.Field.Input,
{
type: "text",
name: "host",
value: host,
placeholder: i18n(
"plugin.tab.settings.input.url.placeholder",
"URL"
),
onChange: (e) => setHost(e.target.value),
disabled: credentials.HostIsFromConfigFile
}
),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
]
}
) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(
designSystem.Field.Root,
{
id: "apiKey",
hint: i18n(
"plugin.tab.settings.input.apiKey.hint",
"A valid API key with enough permission to create indexes (or the master key)."
),
children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: i18n(
"plugin.tab.settings.input.apiKey.label",
"Meilisearch API Key"
) }),
/* @__PURE__ */ jsxRuntime.jsx(
designSystem.Field.Input,
{
type: "password",
name: "apiKey",
placeholder: i18n(
"plugin.tab.settings.input.apiKey.placeholder",
"API key"
),
value: apiKey,
onChange: (e) => setApiKey(e.target.value),
disabled: credentials.ApiKeyIsFromConfigFile
}
),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
]
}
) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 1, paddingLeft: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", style: { color: "red" }, children: [
i18n(
"plugin.tab.settings.warning.credentials.1",
"Do not use this API key on your front-end as it has too much rights. Instead, use the public key available using"
),
" ",
/* @__PURE__ */ jsxRuntime.jsx(
designSystem.Link,
{
isExternal: true,
href: "https://www.meilisearch.com/docs/reference/api/keys#get-keys",
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", style: { color: "red" }, children: i18n(
"plugin.tab.settings.warning.credentials.2",
"the key route"
) })
}
),
"."
] }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 2, paddingLeft: 2, paddingRight: 2, paddingBottom: 2, children: canEdit && /* @__PURE__ */ jsxRuntime.jsx(
designSystem.Button,
{
variant: "secondary",
onClick: () => updateCredentials(),
disabled: credentials.ApiKeyIsFromConfigFile && credentials.HostIsFromConfigFile,
children: i18n("plugin.save", "Save")
}
) })
] });
};
const Credentials$1 = React.memo(Credentials);
const Settings = () => {
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 5, children: /* @__PURE__ */ jsxRuntime.jsx(Credentials$1, {}) });
};
const PluginTabs = () => {
const { i18n } = useI18n();
const { allowedActions: allowedActionsCollection } = admin.useRBAC(
index.PERMISSIONS.collections
);
const { allowedActions: allowedActionsSettings } = admin.useRBAC(
index.PERMISSIONS.settings
);
const canSeeCollections = Object.values(allowedActionsCollection).some(
(value) => !!value
);
const canSeeSettings = Object.values(allowedActionsSettings).some(
(value) => !!value
);
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tabs.Root, { defaultValue: "collections", children: [
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tabs.List, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "collections", children: i18n("plugin.tab.collections", "Collections") }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "settings", children: i18n("plugin.tab.settings", "Settings") })
] }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Content, { value: "collections", children: canSeeCollections && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { color: "neutral800", padding: 4, background: "neutral0", children: /* @__PURE__ */ jsxRuntime.jsx(CollectionTable, {}) }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Content, { value: "settings", children: canSeeSettings && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { color: "neutral800", padding: 4, background: "neutral0", children: /* @__PURE__ */ jsxRuntime.jsx(Settings, {}) }) })
] });
};
const HomePage = () => {
const { i18n } = useI18n();
return /* @__PURE__ */ jsxRuntime.jsx(admin.private_AutoReloadOverlayBlockerProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(admin.Page.Main, { children: [
/* @__PURE__ */ jsxRuntime.jsx(
admin.Layouts.Header,
{
title: i18n("plugin.name", "Meilisearch"),
subtitle: i18n(
"plugin.description",
"Search in your content-types with the Meilisearch plugin"
),
navigationAction: /* @__PURE__ */ jsxRuntime.jsx(admin.BackButton, {})
}
),
/* @__PURE__ */ jsxRuntime.jsx(admin.Layouts.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(PluginTabs, {}) })
] }) });
};
const App = () => {
return /* @__PURE__ */ jsxRuntime.jsx(admin.Page.Protect, { permissions: index.PERMISSIONS.main, children: /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Routes, { children: [
/* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { index: true, element: /* @__PURE__ */ jsxRuntime.jsx(HomePage, {}) }),
/* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "*", element: /* @__PURE__ */ jsxRuntime.jsx(admin.Page.Error, {}) })
] }) });
};
exports.App = App;