@mirrormedia/lilith-draft-editor 3.0.12 → 3.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/lib/index.js +8 -0
  2. package/lib/website/mirrortv/block-renderer/background-image-block.js +93 -0
  3. package/lib/website/mirrortv/block-renderer/background-video-block.js +93 -0
  4. package/lib/website/mirrortv/block-renderer/color-box-block.js +86 -0
  5. package/lib/website/mirrortv/block-renderer/embedded-code-block.js +88 -0
  6. package/lib/website/mirrortv/block-renderer/image-block.js +108 -0
  7. package/lib/website/mirrortv/block-renderer/info-box-block.js +86 -0
  8. package/lib/website/mirrortv/block-renderer/side-index-block.js +90 -0
  9. package/lib/website/mirrortv/block-renderer/slideshow-block.js +150 -0
  10. package/lib/website/mirrortv/block-renderer/table-block.js +408 -0
  11. package/lib/website/mirrortv/block-renderer-fn.js +151 -0
  12. package/lib/website/mirrortv/draft-editor.js +1027 -0
  13. package/lib/website/mirrortv/entity-decorator.js +27 -0
  14. package/lib/website/mirrortv/index.js +16 -0
  15. package/lib/website/mirrortv/selector/align-selector.js +71 -0
  16. package/lib/website/mirrortv/selector/audio-selector.js +279 -0
  17. package/lib/website/mirrortv/selector/image-selector.js +463 -0
  18. package/lib/website/mirrortv/selector/image-uploader.js +260 -0
  19. package/lib/website/mirrortv/selector/pagination.js +82 -0
  20. package/lib/website/mirrortv/selector/post-selector.js +321 -0
  21. package/lib/website/mirrortv/selector/search-box.js +46 -0
  22. package/lib/website/mirrortv/selector/video-selector.js +432 -0
  23. package/lib/website/mirrortv/shared-style/index.js +17 -0
  24. package/lib/website/mirrortv/theme/index.js +28 -0
  25. package/lib/website/mirrortv/utils/file-convert.js +67 -0
  26. package/package.json +3 -3
@@ -0,0 +1,260 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ImageUploader = ImageUploader;
7
+
8
+ var _apollo = require("@keystone-6/core/admin-ui/apollo");
9
+
10
+ var _modals = require("@keystone-ui/modals");
11
+
12
+ var _react = _interopRequireWildcard(require("react"));
13
+
14
+ var _styledComponents = _interopRequireDefault(require("styled-components"));
15
+
16
+ var _fileConvert = require("../utils/file-convert");
17
+
18
+ var _button = require("@keystone-ui/button");
19
+
20
+ var _fields = require("@keystone-ui/fields");
21
+
22
+ var _lodash = _interopRequireDefault(require("lodash"));
23
+
24
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
+
26
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
27
+
28
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
29
+
30
+ const imagesMutation = (0, _apollo.gql)`
31
+ mutation AddImages($data: [ImageCreateInput!]!) {
32
+ images: createImages(data: $data) {
33
+ id
34
+ name
35
+ file {
36
+ url
37
+ width
38
+ height
39
+ }
40
+ resized {
41
+ original
42
+ w480
43
+ w800
44
+ w1200
45
+ w1600
46
+ w2400
47
+ }
48
+ resizedWebp {
49
+ original
50
+ w480
51
+ w800
52
+ w1200
53
+ w1600
54
+ w2400
55
+ }
56
+ }
57
+ }
58
+ `;
59
+ const CustomButton = (0, _styledComponents.default)(_button.Button)`
60
+ margin-top: 10px;
61
+ `;
62
+ const HiddenInput = _styledComponents.default.input`
63
+ display: none;
64
+ `;
65
+ const ImagesWrapper = _styledComponents.default.div`
66
+ overflow: auto;
67
+ margin-top: 10px;
68
+ `;
69
+ const ImageFilesWrapper = _styledComponents.default.div`
70
+ display: flex;
71
+ flex-wrap: wrap;
72
+ overflow: auto;
73
+ `;
74
+ const ImageFileWrapper = _styledComponents.default.div`
75
+ width: 33.3333%;
76
+ cursor: pointer;
77
+ padding: 0 10px 10px;
78
+ `;
79
+ const Image = _styledComponents.default.img`
80
+ display: block;
81
+ width: 100%;
82
+ aspect-ratio: 16 / 9;
83
+ object-fit: contain;
84
+ background: #f0f2f5;
85
+ border-radius: 4px;
86
+ `;
87
+ const ImageNameDisplay = _styledComponents.default.p`
88
+ text-align: center;
89
+ font-size: 0.8rem;
90
+ color: #666;
91
+ margin: 4px 0;
92
+ word-break: break-all;
93
+ `;
94
+ const Label = _styledComponents.default.label`
95
+ display: block;
96
+ margin: 10px 0 5px 0;
97
+ font-weight: 600;
98
+ `;
99
+ const CustomCheckbox = (0, _styledComponents.default)(_fields.Checkbox)`
100
+ display: flex;
101
+ align-items: center;
102
+ cursor: pointer;
103
+ margin-top: 8px;
104
+ `;
105
+ const WatermarkToggleWrapper = _styledComponents.default.div`
106
+ margin-top: 15px;
107
+ padding: 12px;
108
+ background-color: #f7f9fa;
109
+ border: 1px solid #e1e5e9;
110
+ border-radius: 6px;
111
+ `; // --- Types ---
112
+
113
+ // --- Sub Components ---
114
+ const AddImages = ({
115
+ onAddImages
116
+ }) => {
117
+ const inputRef = (0, _react.useRef)(null);
118
+
119
+ const inputChangeHandler = async event => {
120
+ const files = event.target.files;
121
+ event.target.files = null;
122
+ if (!files) return;
123
+ const imagesFiles = await (0, _fileConvert.convertFilesToImageData)(files);
124
+ onAddImages(imagesFiles);
125
+ };
126
+
127
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(CustomButton, {
128
+ weight: "bold",
129
+ tone: "active",
130
+ onClick: () => {
131
+ var _inputRef$current;
132
+
133
+ return (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.click();
134
+ }
135
+ }, "+ \u65B0\u589E\u5716\u7247\u6A94\u6848"), /*#__PURE__*/_react.default.createElement(HiddenInput, {
136
+ type: "file",
137
+ multiple: true,
138
+ accept: "image/*",
139
+ ref: inputRef,
140
+ onChange: inputChangeHandler
141
+ }));
142
+ };
143
+
144
+ function ImageFile({
145
+ file,
146
+ onChange
147
+ }) {
148
+ return /*#__PURE__*/_react.default.createElement(ImageFileWrapper, null, /*#__PURE__*/_react.default.createElement(Image, {
149
+ src: file.blobURL
150
+ }), /*#__PURE__*/_react.default.createElement(ImageNameDisplay, null, file.name), /*#__PURE__*/_react.default.createElement(Label, {
151
+ htmlFor: `name-${file.uid}`
152
+ }, "\u5716\u7247\u6A19\u984C"), /*#__PURE__*/_react.default.createElement(_fields.TextInput, {
153
+ id: `name-${file.uid}`,
154
+ defaultValue: file.name,
155
+ onChange: _lodash.default.debounce(e => {
156
+ onChange({ ...file,
157
+ name: e.target.value
158
+ });
159
+ }, 300)
160
+ }), /*#__PURE__*/_react.default.createElement(CustomCheckbox, {
161
+ checked: file.needWatermark,
162
+ onChange: e => {
163
+ onChange({ ...file,
164
+ needWatermark: e.target.checked
165
+ });
166
+ }
167
+ }, "\u52A0\u4E0A\u6D6E\u6C34\u5370"));
168
+ } // --- Main Component ---
169
+
170
+
171
+ function ImageUploader({
172
+ onChange
173
+ }) {
174
+ const [files, setFiles] = (0, _react.useState)([]);
175
+ const [watermarkAll, setWatermarkAll] = (0, _react.useState)(false);
176
+ const [addImages, {
177
+ data: uploadData,
178
+ loading: uploadLoading,
179
+ error: uploadError
180
+ }] = (0, _apollo.useMutation)(imagesMutation);
181
+
182
+ const onAddImages = rawFiles => {
183
+ const newFiles = rawFiles.map(rawFile => ({ ...rawFile,
184
+ needWatermark: watermarkAll
185
+ }));
186
+ setFiles(prev => prev.concat(newFiles));
187
+ };
188
+
189
+ const onConfirm = async () => {
190
+ if (!files.length) return onChange([]); // 轉換 blob 為 File 物件
191
+
192
+ const tasks = files.map(async data => ({ ...data,
193
+ fileObj: await (0, _fileConvert.convertStringToFile)(data.blobURL, data.name, data.type)
194
+ }));
195
+ const results = await Promise.allSettled(tasks);
196
+ const preparedData = results.filter(res => res.status === 'fulfilled').map(res => res.value);
197
+ addImages({
198
+ variables: {
199
+ data: preparedData.map(d => ({
200
+ name: d.name,
201
+ file: {
202
+ upload: d.fileObj
203
+ },
204
+ needWatermark: d.needWatermark
205
+ }))
206
+ }
207
+ });
208
+ };
209
+
210
+ (0, _react.useEffect)(() => {
211
+ var _uploadData$images;
212
+
213
+ if (uploadData !== null && uploadData !== void 0 && (_uploadData$images = uploadData.images) !== null && _uploadData$images !== void 0 && _uploadData$images.length) {
214
+ onChange(uploadData.images);
215
+ }
216
+ }, [uploadData, onChange]);
217
+ return /*#__PURE__*/_react.default.createElement(_modals.DrawerController, {
218
+ isOpen: true
219
+ }, /*#__PURE__*/_react.default.createElement(_modals.Drawer, {
220
+ title: "\u6279\u6B21\u4E0A\u50B3\u5716\u7247",
221
+ actions: {
222
+ cancel: {
223
+ label: '取消',
224
+ action: () => onChange([])
225
+ },
226
+ confirm: {
227
+ label: uploadLoading ? '上傳中...' : '確認上傳',
228
+ action: onConfirm,
229
+ loading: uploadLoading
230
+ }
231
+ },
232
+ width: "narrow"
233
+ }, /*#__PURE__*/_react.default.createElement("div", {
234
+ style: {
235
+ padding: '4px'
236
+ }
237
+ }, /*#__PURE__*/_react.default.createElement(AddImages, {
238
+ onAddImages: onAddImages
239
+ }), files.length > 0 && /*#__PURE__*/_react.default.createElement(WatermarkToggleWrapper, null, /*#__PURE__*/_react.default.createElement(CustomCheckbox, {
240
+ checked: watermarkAll,
241
+ onChange: e => {
242
+ const checked = e.target.checked;
243
+ setWatermarkAll(checked);
244
+ setFiles(prev => prev.map(f => ({ ...f,
245
+ needWatermark: checked
246
+ })));
247
+ }
248
+ }, /*#__PURE__*/_react.default.createElement("strong", null, "\u6240\u6709\u5716\u7247\u5747\u52A0\u4E0A\u6D6E\u6C34\u5370"))), /*#__PURE__*/_react.default.createElement(ImagesWrapper, null, /*#__PURE__*/_react.default.createElement(ImageFilesWrapper, null, files.map(file => /*#__PURE__*/_react.default.createElement(ImageFile, {
249
+ key: file.uid,
250
+ file: file,
251
+ onChange: updatedFile => {
252
+ setFiles(prev => prev.map(f => f.uid === updatedFile.uid ? updatedFile : f));
253
+ }
254
+ })))), uploadError && /*#__PURE__*/_react.default.createElement("div", {
255
+ style: {
256
+ color: '#de350b',
257
+ marginTop: '15px'
258
+ }
259
+ }, "\u4E0A\u50B3\u5931\u6557\uFF1A", uploadError.message))));
260
+ }
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Pagination = Pagination;
7
+
8
+ var _react = _interopRequireDefault(require("react"));
9
+
10
+ var _styledComponents = _interopRequireDefault(require("styled-components"));
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ const PaginationWrapper = _styledComponents.default.div`
15
+ display: flex;
16
+ justify-content: end;
17
+ `;
18
+ const Arrows = _styledComponents.default.div`
19
+ display: flex;
20
+ `;
21
+ const ArrowButtonWrapper = _styledComponents.default.a`
22
+ color: #415269;
23
+ cursor: pointer;
24
+ ${({
25
+ disable
26
+ }) => {
27
+ if (disable) {
28
+ return `
29
+ pointer-events: none;
30
+ opacity: 0.65;
31
+ cursor: unset;
32
+ `;
33
+ }
34
+ }}
35
+ `;
36
+
37
+ function Pagination({
38
+ currentPage,
39
+ total,
40
+ pageSize,
41
+ onChange
42
+ }) {
43
+ const minPage = 1;
44
+ const limit = Math.ceil(total / pageSize);
45
+ const nextPage = currentPage + 1;
46
+ const prevPage = currentPage - 1; // Don't render the pagiantion component if the pageSize is greater than the total number of items in the list.
47
+
48
+ if (total <= pageSize) return null;
49
+ return /*#__PURE__*/_react.default.createElement(PaginationWrapper, null, /*#__PURE__*/_react.default.createElement("div", null, currentPage, " of ", limit, " pages"), /*#__PURE__*/_react.default.createElement(Arrows, null, /*#__PURE__*/_react.default.createElement(ArrowButtonWrapper, {
50
+ onClick: () => {
51
+ onChange(prevPage);
52
+ },
53
+ disable: prevPage < minPage
54
+ }, /*#__PURE__*/_react.default.createElement("svg", {
55
+ "aria-hidden": "true",
56
+ focusable: "false",
57
+ height: "24px",
58
+ width: "24px",
59
+ role: "img",
60
+ viewBox: "0 0 24 24",
61
+ xmlns: "http://www.w3.org/2000/svg",
62
+ className: "css-bztyua"
63
+ }, /*#__PURE__*/_react.default.createElement("polyline", {
64
+ points: "15 18 9 12 15 6"
65
+ }), ' ')), /*#__PURE__*/_react.default.createElement(ArrowButtonWrapper, {
66
+ onClick: () => {
67
+ onChange(nextPage);
68
+ },
69
+ disable: nextPage > limit
70
+ }, /*#__PURE__*/_react.default.createElement("svg", {
71
+ "aria-hidden": "true",
72
+ focusable: "false",
73
+ height: "24px",
74
+ width: "24px",
75
+ role: "img",
76
+ viewBox: "0 0 24 24",
77
+ xmlns: "http://www.w3.org/2000/svg",
78
+ className: "css-bztyua"
79
+ }, /*#__PURE__*/_react.default.createElement("polyline", {
80
+ points: "9 18 15 12 9 6"
81
+ })))));
82
+ }
@@ -0,0 +1,321 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.PostSelector = PostSelector;
7
+
8
+ var _react = _interopRequireWildcard(require("react"));
9
+
10
+ var _styledComponents = _interopRequireDefault(require("styled-components"));
11
+
12
+ var _modals = require("@keystone-ui/modals");
13
+
14
+ var _apollo = require("@keystone-6/core/admin-ui/apollo");
15
+
16
+ var _searchBox = require("./search-box");
17
+
18
+ var _pagination = require("./pagination");
19
+
20
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
+
22
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
23
+
24
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
25
+
26
+ const postsQuery = (0, _apollo.gql)`
27
+ query Posts($searchText: String!, $take: Int, $skip: Int) {
28
+ postsCount(where: { title: { contains: $searchText } })
29
+ posts(
30
+ where: { title: { contains: $searchText } }
31
+ orderBy: { id: desc }
32
+ take: $take
33
+ skip: $skip
34
+ ) {
35
+ id
36
+ slug
37
+ title
38
+ subtitle
39
+ heroImage {
40
+ id
41
+ name
42
+ imageFile {
43
+ url
44
+ }
45
+ resized {
46
+ original
47
+ }
48
+ }
49
+ og_image {
50
+ id
51
+ name
52
+ imageFile {
53
+ url
54
+ }
55
+ resized {
56
+ original
57
+ }
58
+ }
59
+ }
60
+ }
61
+ `;
62
+ const PostSearchBox = (0, _styledComponents.default)(_searchBox.SearchBox)`
63
+ margin-top: 10px;
64
+ `;
65
+ const PostSelectionWrapper = _styledComponents.default.div`
66
+ overflow: auto;
67
+ margin-top: 10px;
68
+ `;
69
+ const PostGridsWrapper = _styledComponents.default.div`
70
+ display: flex;
71
+ flex-wrap: wrap;
72
+ overflow: auto;
73
+ `;
74
+ const PostGridWrapper = _styledComponents.default.div`
75
+ flex: 0 0 33.3333%;
76
+ cursor: pointer;
77
+ padding: 0 10px 10px;
78
+ `;
79
+ const PostMetaGridsWrapper = _styledComponents.default.div`
80
+ display: flex;
81
+ flex-wrap: wrap;
82
+ overflow: auto;
83
+ `;
84
+ const PostMetaGridWrapper = _styledComponents.default.div`
85
+ flex: 0 0 33.3333%;
86
+ cursor: pointer;
87
+ padding: 0 10px 10px;
88
+ `;
89
+ const Post = _styledComponents.default.div`
90
+ width: 100%;
91
+ `;
92
+ const SeparationLine = _styledComponents.default.div`
93
+ border: #e1e5e9 1px solid;
94
+ margin-top: 10px;
95
+ margin-bottom: 10px;
96
+ `;
97
+ const ErrorHint = _styledComponents.default.span`
98
+ color: red;
99
+ `;
100
+ const PostSelected = _styledComponents.default.div`
101
+ height: 1.4rem;
102
+ `;
103
+ const PostImage = _styledComponents.default.img`
104
+ display: block;
105
+ width: 100%;
106
+ aspect-ratio: 2;
107
+ object-fit: cover;
108
+ `;
109
+ const PostTitle = _styledComponents.default.div`
110
+ padding: 0 5px;
111
+ `;
112
+ const ErrorWrapper = _styledComponents.default.div`
113
+ & * {
114
+ margin: 0;
115
+ }
116
+ `;
117
+
118
+ function PostGrids(props) {
119
+ const {
120
+ posts,
121
+ selected,
122
+ onSelect
123
+ } = props;
124
+ return /*#__PURE__*/_react.default.createElement(PostGridsWrapper, null, posts.map(post => {
125
+ return /*#__PURE__*/_react.default.createElement(PostGrid, {
126
+ key: post.id,
127
+ isSelected: selected === null || selected === void 0 ? void 0 : selected.includes(post),
128
+ onSelect: () => onSelect(post),
129
+ post: post
130
+ });
131
+ }));
132
+ }
133
+
134
+ function PostGrid(props) {
135
+ var _post$heroImage, _post$heroImage$resiz;
136
+
137
+ const {
138
+ post,
139
+ onSelect,
140
+ isSelected
141
+ } = props;
142
+ return /*#__PURE__*/_react.default.createElement(PostGridWrapper, {
143
+ key: post === null || post === void 0 ? void 0 : post.id,
144
+ onClick: () => onSelect(post)
145
+ }, /*#__PURE__*/_react.default.createElement(PostSelected, null, isSelected ? /*#__PURE__*/_react.default.createElement("i", {
146
+ className: "fas fa-check-circle"
147
+ }) : null), /*#__PURE__*/_react.default.createElement(Post, null, /*#__PURE__*/_react.default.createElement(PostImage, {
148
+ src: (_post$heroImage = post.heroImage) === null || _post$heroImage === void 0 ? void 0 : (_post$heroImage$resiz = _post$heroImage.resized) === null || _post$heroImage$resiz === void 0 ? void 0 : _post$heroImage$resiz.original,
149
+ onError: e => {
150
+ var _post$heroImage2, _post$heroImage2$imag;
151
+
152
+ return e.currentTarget.src = (_post$heroImage2 = post.heroImage) === null || _post$heroImage2 === void 0 ? void 0 : (_post$heroImage2$imag = _post$heroImage2.imageFile) === null || _post$heroImage2$imag === void 0 ? void 0 : _post$heroImage2$imag.url;
153
+ }
154
+ }), /*#__PURE__*/_react.default.createElement(PostTitle, null, post.title)));
155
+ }
156
+
157
+ function PostMetaGrids(props) {
158
+ const {
159
+ postMetas
160
+ } = props;
161
+ return /*#__PURE__*/_react.default.createElement(PostMetaGridsWrapper, null, postMetas.map(postMetas => {
162
+ var _postMetas$post;
163
+
164
+ return /*#__PURE__*/_react.default.createElement(PostMetaGrid, {
165
+ key: postMetas === null || postMetas === void 0 ? void 0 : (_postMetas$post = postMetas.post) === null || _postMetas$post === void 0 ? void 0 : _postMetas$post.id,
166
+ postMeta: postMetas
167
+ });
168
+ }));
169
+ }
170
+
171
+ function PostMetaGrid(props) {
172
+ var _post$heroImage3, _post$heroImage3$resi;
173
+
174
+ const {
175
+ postMeta
176
+ } = props;
177
+ const {
178
+ post
179
+ } = postMeta;
180
+ return /*#__PURE__*/_react.default.createElement(PostMetaGridWrapper, null, /*#__PURE__*/_react.default.createElement(Post, null, /*#__PURE__*/_react.default.createElement(PostImage, {
181
+ src: post === null || post === void 0 ? void 0 : (_post$heroImage3 = post.heroImage) === null || _post$heroImage3 === void 0 ? void 0 : (_post$heroImage3$resi = _post$heroImage3.resized) === null || _post$heroImage3$resi === void 0 ? void 0 : _post$heroImage3$resi.original,
182
+ onError: e => {
183
+ var _post$heroImage4, _post$heroImage4$imag;
184
+
185
+ return e.currentTarget.src = post === null || post === void 0 ? void 0 : (_post$heroImage4 = post.heroImage) === null || _post$heroImage4 === void 0 ? void 0 : (_post$heroImage4$imag = _post$heroImage4.imageFile) === null || _post$heroImage4$imag === void 0 ? void 0 : _post$heroImage4$imag.url;
186
+ }
187
+ }), /*#__PURE__*/_react.default.createElement(PostTitle, null, post === null || post === void 0 ? void 0 : post.title)));
188
+ }
189
+
190
+ function PostSelector(props) {
191
+ const [queryPosts, {
192
+ loading,
193
+ error,
194
+ data: {
195
+ posts = [],
196
+ postsCount = 0
197
+ } = {}
198
+ }] = (0, _apollo.useLazyQuery)(postsQuery, {
199
+ fetchPolicy: 'no-cache'
200
+ });
201
+ const [currentPage, setCurrentPage] = (0, _react.useState)(0); // page starts with 1, 0 is used to detect initialization
202
+
203
+ const [searchText, setSearchText] = (0, _react.useState)('');
204
+ const [selected, setSelected] = (0, _react.useState)([]);
205
+ const [showErrorHint, setShowErrorHint] = (0, _react.useState)(false);
206
+ const pageSize = 6;
207
+ const {
208
+ onChange,
209
+ enableMultiSelect = false,
210
+ minSelectCount = 1,
211
+ maxSelectCount = 3
212
+ } = props;
213
+
214
+ const onSave = () => {
215
+ if (enableMultiSelect && minSelectCount && selected.length < minSelectCount) {
216
+ setShowErrorHint(true);
217
+ return;
218
+ }
219
+
220
+ onChange(selected);
221
+ };
222
+
223
+ const onCancel = () => {
224
+ onChange([]);
225
+ };
226
+
227
+ const onSearchBoxChange = async searchInput => {
228
+ setSearchText(searchInput);
229
+ setCurrentPage(1);
230
+ };
231
+
232
+ const onPostsGridSelect = postEntity => {
233
+ setSelected(selected => {
234
+ const filterdSelected = selected.filter(ele => {
235
+ var _ele$post;
236
+
237
+ return ((_ele$post = ele.post) === null || _ele$post === void 0 ? void 0 : _ele$post.id) !== postEntity.id;
238
+ }); // deselect the post
239
+
240
+ if (filterdSelected.length !== selected.length) {
241
+ return filterdSelected;
242
+ } // add new selected one and check shrink the array if there is a limit
243
+
244
+
245
+ if (enableMultiSelect) {
246
+ let newSelected = selected.concat([{
247
+ post: postEntity
248
+ }]);
249
+
250
+ if (maxSelectCount && newSelected.length >= maxSelectCount) {
251
+ newSelected = newSelected.slice(-maxSelectCount);
252
+ }
253
+
254
+ return newSelected;
255
+ } // single select
256
+
257
+
258
+ return [{
259
+ post: postEntity
260
+ }];
261
+ });
262
+ };
263
+
264
+ const selectedPosts = selected.map(ele => {
265
+ return ele.post;
266
+ });
267
+ (0, _react.useEffect)(() => {
268
+ if (currentPage !== 0) {
269
+ queryPosts({
270
+ variables: {
271
+ searchText: searchText,
272
+ skip: (currentPage - 1) * pageSize,
273
+ take: pageSize
274
+ }
275
+ });
276
+ }
277
+ }, [currentPage, searchText]);
278
+
279
+ let searchResult = /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(PostGrids, {
280
+ posts: posts,
281
+ selected: selectedPosts,
282
+ onSelect: onPostsGridSelect
283
+ }), /*#__PURE__*/_react.default.createElement(_pagination.Pagination, {
284
+ currentPage: currentPage,
285
+ total: postsCount,
286
+ pageSize: pageSize,
287
+ onChange: pageIndex => {
288
+ setCurrentPage(pageIndex);
289
+ }
290
+ }));
291
+
292
+ if (loading) {
293
+ searchResult = /*#__PURE__*/_react.default.createElement("p", null, "searching...");
294
+ }
295
+
296
+ if (error) {
297
+ var _postsQuery$loc;
298
+
299
+ searchResult = /*#__PURE__*/_react.default.createElement(ErrorWrapper, null, /*#__PURE__*/_react.default.createElement("h3", null, "Errors occurs in the `posts` query"), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("b", null, "Message:"), /*#__PURE__*/_react.default.createElement("div", null, error.message), /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("b", null, "Stack:"), /*#__PURE__*/_react.default.createElement("div", null, error.stack), /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("b", null, "Query:"), /*#__PURE__*/_react.default.createElement("pre", null, postsQuery === null || postsQuery === void 0 ? void 0 : (_postsQuery$loc = postsQuery.loc) === null || _postsQuery$loc === void 0 ? void 0 : _postsQuery$loc.source.body)));
300
+ }
301
+
302
+ return /*#__PURE__*/_react.default.createElement(_modals.DrawerController, {
303
+ isOpen: true
304
+ }, /*#__PURE__*/_react.default.createElement(_modals.Drawer, {
305
+ title: "Select post",
306
+ actions: {
307
+ cancel: {
308
+ label: 'Cancel',
309
+ action: onCancel
310
+ },
311
+ confirm: {
312
+ label: 'Confirm',
313
+ action: onSave
314
+ }
315
+ }
316
+ }, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(PostSearchBox, {
317
+ onChange: onSearchBoxChange
318
+ }), /*#__PURE__*/_react.default.createElement(PostSelectionWrapper, null, /*#__PURE__*/_react.default.createElement("div", null, searchResult, " "), !!selected.length && /*#__PURE__*/_react.default.createElement(SeparationLine, null), /*#__PURE__*/_react.default.createElement(PostMetaGrids, {
319
+ postMetas: selected
320
+ }), showErrorHint && /*#__PURE__*/_react.default.createElement(ErrorHint, null, "\u8ACB\u81F3\u5C11\u9078\u64C7", minSelectCount, "\u5247\u6587\u7AE0")))));
321
+ }