burdy
Version:
Open Source Headless Platform
225 lines (224 loc) • 11.5 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importStar(require("react"));
const react_hook_form_1 = require("react-hook-form");
const react_2 = require("@fluentui/react");
const hoc_1 = require("../helpers/hoc");
const posts_context_1 = require("../features/posts/context/posts.context");
const empty_1 = __importDefault(require("../components/empty"));
const posts_select_panel_1 = __importDefault(require("../features/posts/components/posts-select-panel"));
const dynamic_form_1 = require("./dynamic-form");
const styles = (0, react_2.mergeStyleSets)({
postsWrapper: {
minHeight: 240,
overflow: 'auto',
},
});
const PostsList = ({ posts, onPostsChange }) => {
var _a;
const { selection, getPosts } = (0, posts_context_1.usePosts)();
const [postsVal, setPostsVal] = (0, react_1.useState)([]);
(0, react_1.useEffect)(() => {
if ((posts === null || posts === void 0 ? void 0 : posts.length) > 0) {
getPosts.execute({
slug: (posts || []).map((post) => post === null || post === void 0 ? void 0 : post.slugPath).join(','),
});
}
else {
getPosts.reset();
}
}, [posts]);
(0, react_1.useEffect)(() => {
if (postsVal.length === 0)
return;
onPostsChange === null || onPostsChange === void 0 ? void 0 : onPostsChange(postsVal);
}, [postsVal]);
(0, react_1.useEffect)(() => {
const result = [...((getPosts === null || getPosts === void 0 ? void 0 : getPosts.result) || [])];
result.sort((a, b) => {
const aIndex = posts.findIndex((post) => post.slugPath == a.slugPath);
const bIndex = posts.findIndex((post) => post.slugPath == b.slugPath);
return aIndex - bIndex;
});
setPostsVal(result);
}, [getPosts === null || getPosts === void 0 ? void 0 : getPosts.result]);
const columns = (0, react_1.useMemo)(() => [
{
key: 'name',
name: 'Name',
fieldName: 'name',
minWidth: 210,
isRowHeader: true,
data: 'string',
onRender: (item) => {
return react_1.default.createElement("div", null, item === null || item === void 0 ? void 0 : item.name);
},
isPadded: true,
},
{
key: 'slugPath',
name: 'Path',
fieldName: 'slugPath',
minWidth: 300,
isRowHeader: true,
data: 'string'
},
{
key: 'contentType',
name: 'Content Type',
fieldName: 'contentType',
minWidth: 210,
isResizable: true,
data: 'string',
onRender: ({ contentType }) => {
return react_1.default.createElement("div", null, contentType === null || contentType === void 0 ? void 0 : contentType.name);
},
isPadded: true,
},
{
key: 'action',
name: '',
fieldName: 'action',
minWidth: 60,
maxWidth: 60,
onRender: ({ contentType, contentTypeId, id, parentId }) => (react_1.default.createElement(react_2.IconButton, { iconProps: {
iconName: 'OpenInNewTab',
}, title: "Open in new tab", onClick: () => {
window.open(`/admin/sites/editor/${id}`, '_blank');
} })),
},
], []);
if (!(getPosts === null || getPosts === void 0 ? void 0 : getPosts.loading) &&
(!(getPosts === null || getPosts === void 0 ? void 0 : getPosts.result) || ((_a = getPosts === null || getPosts === void 0 ? void 0 : getPosts.result) === null || _a === void 0 ? void 0 : _a.length) === 0)) {
return (react_1.default.createElement("div", { className: styles.postsWrapper },
react_1.default.createElement(empty_1.default, { compact: true, title: "No relations", image: "posts" })));
}
return (react_1.default.createElement("div", { className: styles.postsWrapper },
react_1.default.createElement(react_2.MarqueeSelection, { selection: selection, isDraggingConstrainedToRoot: true },
react_1.default.createElement(react_2.ShimmeredDetailsList, { items: postsVal || [], columns: columns, enableShimmer: getPosts === null || getPosts === void 0 ? void 0 : getPosts.loading, selectionMode: react_2.SelectionMode.multiple, setKey: "multiple", layoutMode: react_2.DetailsListLayoutMode.justified, isHeaderVisible: true, selection: selection, selectionPreservedOnEmptyClick: true, ariaLabelForSelectionColumn: "Toggle selection", ariaLabelForSelectAllCheckbox: "Toggle selection for all items", checkButtonAriaLabel: "select row" }))));
};
const DynamicRelation = ({ field, name }) => {
const { control, disabled } = (0, dynamic_form_1.useExtendedFormContext)();
const { selectedPosts } = (0, posts_context_1.usePosts)();
const [addPostOpen, setAddPostOpen] = (0, react_1.useState)(false);
const selectedItem = (0, react_1.useMemo)(() => {
if ((selectedPosts === null || selectedPosts === void 0 ? void 0 : selectedPosts.length) === 1) {
return selectedPosts === null || selectedPosts === void 0 ? void 0 : selectedPosts[0];
}
return undefined;
}, [selectedPosts]);
return (react_1.default.createElement(react_hook_form_1.Controller, { name: name, control: control, defaultValue: [], render: ({ field: { onChange, value: fieldValue } }) => {
var _a;
const value = (0, react_1.useMemo)(() => {
let val = [];
try {
val = JSON.parse(fieldValue);
}
catch (_a) {
//
}
return val;
}, [fieldValue]);
const selectedItemIndex = (0, react_1.useMemo)(() => {
return (value || []).findIndex((item) => (item === null || item === void 0 ? void 0 : item.slugPath) == (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.slugPath));
}, [value, selectedItem]);
const move = (offset) => {
const items = [
...(value || []).filter((_val, i) => i !== selectedItemIndex),
];
items.splice(selectedItemIndex + offset, 0, {
slugPath: selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.slugPath,
});
onChange(JSON.stringify(items));
};
const commandItems = (0, react_1.useMemo)(() => [
{
key: 'addPost',
text: 'Add',
disabled: !!disabled,
iconProps: { iconName: 'Add' },
onClick: () => {
setAddPostOpen(true);
},
},
{
key: 'remove',
text: 'Remove',
disabled: disabled || !(selectedPosts === null || selectedPosts === void 0 ? void 0 : selectedPosts.length) || (selectedPosts === null || selectedPosts === void 0 ? void 0 : selectedPosts.length) === 0,
iconProps: { iconName: 'Delete' },
onClick: () => {
onChange(JSON.stringify((value !== null && value !== void 0 ? value : []).filter((post) => selectedPosts.every((selected) => (selected === null || selected === void 0 ? void 0 : selected.slugPath) != post.slugPath))));
},
},
{
key: 'moveUp',
disabled: disabled || (selectedPosts === null || selectedPosts === void 0 ? void 0 : selectedPosts.length) !== 1 || selectedItemIndex === 0,
iconProps: { iconName: 'Up' },
onClick: () => {
move(-1);
},
},
{
key: 'moveDown',
disabled: disabled ||
(selectedPosts === null || selectedPosts === void 0 ? void 0 : selectedPosts.length) !== 1 ||
selectedItemIndex >= (value || []).length - 1,
iconProps: { iconName: 'Down' },
onClick: () => {
move(1);
},
},
], [selectedPosts]);
return (react_1.default.createElement(react_1.default.Fragment, null,
((_a = field === null || field === void 0 ? void 0 : field.label) === null || _a === void 0 ? void 0 : _a.length) > 0 && react_1.default.createElement(react_2.Label, null, field === null || field === void 0 ? void 0 : field.label),
react_1.default.createElement(react_2.CommandBar, { styles: {
root: {
padding: 0,
marginBottom: 8,
},
}, items: commandItems }),
react_1.default.createElement(PostsList, { posts: value, onPostsChange: (data) => {
onChange(JSON.stringify((data || []).map((item) => ({
slugPath: item === null || item === void 0 ? void 0 : item.slugPath,
}))));
} }),
react_1.default.createElement(posts_select_panel_1.default, { isOpen: addPostOpen, onDismiss: () => setAddPostOpen(false), onSubmit: (data) => {
onChange(JSON.stringify([
...(Array.isArray(value) ? value : []).filter((val) => Boolean(val === null || val === void 0 ? void 0 : val.slugPath)),
...data
.filter((post) => !(value || []).find((val) => val.slugPath == post.slugPath))
.map((post) => ({
slugPath: post.slugPath,
})),
]));
setAddPostOpen(false);
}, params: {
contentTypeName: field.posts,
} })));
} }));
};
exports.default = (0, hoc_1.composeWrappers)({
postsContext: posts_context_1.PostsContextProvider,
})(DynamicRelation);