@webiny/app-headless-cms 5.19.1-beta.0 → 5.20.0-beta.2

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.
@@ -1,3 +1,10 @@
1
1
  import React from "react";
2
- declare const _default: React.MemoExoticComponent<(props: any) => JSX.Element>;
2
+ import { CmsEditorField } from "../../../types";
3
+ export interface Props {
4
+ field: CmsEditorField;
5
+ onDelete: Function;
6
+ onEdit: Function;
7
+ parent?: CmsEditorField;
8
+ }
9
+ declare const _default: React.NamedExoticComponent<Props>;
3
10
  export default _default;
@@ -133,12 +133,13 @@ var Field = function Field(props) {
133
133
  return null;
134
134
  }
135
135
 
136
+ var isTitleField = field.fieldId === data.titleFieldId && !parent;
136
137
  var lockedFields = data.lockedFields || [];
137
138
  return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(FieldContainer, null, /*#__PURE__*/React.createElement(Info, null, /*#__PURE__*/React.createElement(Typography, {
138
139
  use: "subtitle1"
139
140
  }, field.label), /*#__PURE__*/React.createElement(Typography, {
140
141
  use: "caption"
141
- }, fieldPlugin.field.label, " ", field.multipleValues && /*#__PURE__*/React.createElement(React.Fragment, null, "(", t(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["multiple values"]))), ")"), field.fieldId === data.titleFieldId && /*#__PURE__*/React.createElement(React.Fragment, null, "(", t(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["entry title"]))), ")"))), /*#__PURE__*/React.createElement(Actions, null, /*#__PURE__*/React.createElement(IconButton, {
142
+ }, fieldPlugin.field.label, " ", field.multipleValues && /*#__PURE__*/React.createElement(React.Fragment, null, "(", t(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["multiple values"]))), ")"), isTitleField && /*#__PURE__*/React.createElement(React.Fragment, null, "(", t(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["entry title"]))), ")"))), /*#__PURE__*/React.createElement(Actions, null, /*#__PURE__*/React.createElement(IconButton, {
142
143
  "data-testid": "cms.editor.edit-field",
143
144
  icon: /*#__PURE__*/React.createElement(EditIcon, null),
144
145
  onClick: function onClick() {
@@ -1,5 +1,6 @@
1
1
  export { default as useCms } from "./useCms";
2
2
  export { default as useQuery } from "./useQuery";
3
+ export * from "./useQueryLocale";
3
4
  export { default as useLazyQuery } from "./useLazyQuery";
4
5
  export { default as useMutation } from "./useMutation";
5
6
  export { default as useApolloClient } from "./useApolloClient";
@@ -1,5 +1,6 @@
1
1
  export { default as useCms } from "./useCms";
2
2
  export { default as useQuery } from "./useQuery";
3
+ export * from "./useQueryLocale";
3
4
  export { default as useLazyQuery } from "./useLazyQuery";
4
5
  export { default as useMutation } from "./useMutation";
5
6
  export { default as useApolloClient } from "./useApolloClient";
@@ -0,0 +1,2 @@
1
+ import { DocumentNode } from "graphql";
2
+ export declare const useQueryLocale: (query: DocumentNode, locale: string, options?: {}) => import("@apollo/react-common").QueryResult<any, Record<string, any>>;
@@ -0,0 +1,15 @@
1
+ import _objectSpread from "@babel/runtime/helpers/objectSpread2";
2
+ import useCms from "./useCms";
3
+ import { useQuery as apolloUseQuery } from "@apollo/react-hooks";
4
+ export var useQueryLocale = function useQueryLocale(query, locale) {
5
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
6
+
7
+ var _useCms = useCms(),
8
+ getApolloClient = _useCms.getApolloClient;
9
+
10
+ var client = getApolloClient(locale);
11
+ return apolloUseQuery(query, _objectSpread({
12
+ client: client,
13
+ skip: !client
14
+ }, options));
15
+ };
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="24px"
4
+ height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
5
+ <g id="Bounding_Boxes" display="none">
6
+ <path display="inline" fill="none" d="M0,0h24v24H0V0z"/>
7
+ </g>
8
+ <g id="Rounded">
9
+ <path d="M3,6L3,6C2.45,6,2,6.45,2,7v13c0,1.1,0.9,2,2,2h13c0.55,0,1-0.45,1-1v0c0-0.55-0.45-1-1-1H5c-0.55,0-1-0.45-1-1V7
10
+ C4,6.45,3.55,6,3,6z M20,2H8C6.9,2,6,2.9,6,4v12c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C22,2.9,21.1,2,20,2z M18,11h-3v3
11
+ c0,0.55-0.45,1-1,1h0c-0.55,0-1-0.45-1-1v-3h-3c-0.55,0-1-0.45-1-1v0c0-0.55,0.45-1,1-1h3V6c0-0.55,0.45-1,1-1h0c0.55,0,1,0.45,1,1
12
+ v3h3c0.55,0,1,0.45,1,1v0C19,10.55,18.55,11,18,11z"/>
13
+ </g>
14
+ </svg>
@@ -13,6 +13,10 @@ var throwTransformError = function throwTransformError(params) {
13
13
  };
14
14
 
15
15
  var dateOnly = function dateOnly(value) {
16
+ if (!value) {
17
+ return new Date().toISOString().substr(0, 10);
18
+ }
19
+
16
20
  try {
17
21
  var date = new Date(value).toISOString();
18
22
  return date.substr(0, 10);
@@ -28,7 +32,9 @@ var dateOnly = function dateOnly(value) {
28
32
  var extractTimeZone = function extractTimeZone(value) {
29
33
  var result;
30
34
 
31
- if (value.includes("+")) {
35
+ if (!value) {
36
+ return [new Date().toISOString(), "00:00"];
37
+ } else if (value.includes("+")) {
32
38
  result = value.split("+");
33
39
  } else {
34
40
  result = value.split("-");
@@ -44,7 +50,9 @@ var extractTimeZone = function extractTimeZone(value) {
44
50
  };
45
51
 
46
52
  var extractTime = function extractTime(value) {
47
- if (value.includes(":") === false) {
53
+ if (!value) {
54
+ return "00:00:00";
55
+ } else if (value.includes(":") === false) {
48
56
  throw new WebinyError("Time value is missing : separators.", "TIME_ERROR", {
49
57
  value: value
50
58
  });
@@ -60,7 +68,11 @@ var extractTime = function extractTime(value) {
60
68
  };
61
69
 
62
70
  var dateTimeWithTimezone = function dateTimeWithTimezone(value) {
63
- if (value.includes("T") === false) {
71
+ if (!value) {
72
+ var _date = new Date().toISOString();
73
+
74
+ return _date.replace(/\.([0-9]+)Z/, "+00:00");
75
+ } else if (value.includes("T") === false) {
64
76
  return value;
65
77
  }
66
78
 
@@ -91,7 +103,9 @@ var dateTimeWithTimezone = function dateTimeWithTimezone(value) {
91
103
  };
92
104
 
93
105
  var dateTimeWithoutTimezone = function dateTimeWithoutTimezone(value) {
94
- if (value.includes(" ") === false) {
106
+ if (!value) {
107
+ return new Date().toISOString();
108
+ } else if (value.includes(" ") === false) {
95
109
  return value;
96
110
  }
97
111
 
@@ -106,8 +120,16 @@ var dateTimeWithoutTimezone = function dateTimeWithoutTimezone(value) {
106
120
  }
107
121
  };
108
122
 
123
+ var time = function time(value) {
124
+ if (!value) {
125
+ return "00:00:00";
126
+ }
127
+
128
+ return extractTime(value);
129
+ };
130
+
109
131
  var transformers = {
110
- time: null,
132
+ time: time,
111
133
  date: dateOnly,
112
134
  dateTimeWithoutTimezone: dateTimeWithoutTimezone,
113
135
  dateTimeWithTimezone: dateTimeWithTimezone
@@ -120,12 +142,6 @@ export default (function () {
120
142
  transform: function transform(value, field) {
121
143
  // check types in packages/app-headless-cms/src/admin/plugins/fieldRenderers/dateTime/dateTimeField.tsx
122
144
  var type = field.settings.type;
123
-
124
- if (!value) {
125
- console.log("Field \"".concat(field.fieldId, "\" has no value."));
126
- return null;
127
- }
128
-
129
145
  var transform = transformers[type];
130
146
 
131
147
  if (!transform) {
@@ -1,2 +1,2 @@
1
1
  import { CmsEditorContentModel } from "../../../../types";
2
- export declare const prepareFormData: (data: Record<string, any>, model: CmsEditorContentModel) => Record<string, any>;
2
+ export declare const prepareFormData: (input: Record<string, any>, model: CmsEditorContentModel) => Record<string, any>;
@@ -63,17 +63,18 @@ var createTransformers = function createTransformers(fields) {
63
63
  return transformers;
64
64
  };
65
65
 
66
- export var prepareFormData = function prepareFormData(data, model) {
66
+ export var prepareFormData = function prepareFormData(input, model) {
67
67
  var transformers = createTransformers(model.fields);
68
- return Object.keys(data).reduce(function (acc, key) {
69
- var value = data[key];
68
+ return Object.keys(transformers).reduce(function (output, key) {
69
+ var value = input[key];
70
+ var transform = transformers[key];
71
+ var transformedValue = transform(value);
70
72
 
71
- if (!transformers[key]) {
72
- acc[key] = value;
73
- return acc;
73
+ if (transformedValue === undefined) {
74
+ return output;
74
75
  }
75
76
 
76
- acc[key] = transformers[key](value);
77
- return acc;
78
- }, {});
77
+ output[key] = transformedValue;
78
+ return output;
79
+ }, input);
79
80
  };
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import * as UID from "@webiny/ui/Dialog";
3
+ import { CmsEditorContentModel } from "../../../types";
4
+ export interface Props {
5
+ open: boolean;
6
+ onClose: UID.DialogOnClose;
7
+ contentModel: CmsEditorContentModel;
8
+ closeModal: () => void;
9
+ }
10
+ declare const CloneContentModelDialog: React.FC<Props>;
11
+ export default CloneContentModelDialog;
@@ -0,0 +1,272 @@
1
+ import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+ import _createForOfIteratorHelper from "@babel/runtime/helpers/createForOfIteratorHelper";
4
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
+
6
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9;
7
+
8
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
9
+ import React, { useCallback } from "react";
10
+ import { css } from "emotion";
11
+ import get from "lodash/get";
12
+ import { useRouter } from "@webiny/react-router";
13
+ import { Form } from "@webiny/form";
14
+ import { Input } from "@webiny/ui/Input";
15
+ import { Select } from "@webiny/ui/Select";
16
+ import { useSnackbar } from "@webiny/app-admin/hooks/useSnackbar";
17
+ import { CircularProgress } from "@webiny/ui/Progress";
18
+ import { validation } from "@webiny/validation";
19
+ import { useMutation, useQueryLocale } from "../../hooks";
20
+ import { i18n } from "@webiny/app/i18n";
21
+ import { ButtonDefault } from "@webiny/ui/Button";
22
+ import * as UID from "@webiny/ui/Dialog";
23
+ import { Grid, Cell } from "@webiny/ui/Grid";
24
+ import { addModelToGroupCache, addModelToListCache } from "./cache";
25
+ import * as GQL from "../../viewsGraphql";
26
+ import { useI18N } from "@webiny/app-i18n/hooks/useI18N";
27
+ var t = i18n.ns("app-headless-cms/admin/views/content-models/clone-content-model-dialog");
28
+ var narrowDialog = /*#__PURE__*/css({
29
+ ".mdc-dialog__surface": {
30
+ width: 600,
31
+ minWidth: 600
32
+ }
33
+ }, "label:narrowDialog;");
34
+ var noPadding = /*#__PURE__*/css({
35
+ padding: "5px !important"
36
+ }, "label:noPadding;");
37
+
38
+ /**
39
+ * This list is to disallow creating models that might interfere with GraphQL schema creation.
40
+ * Add more if required.
41
+ */
42
+ var disallowedModelIdEndingList = ["Response", "List", "Meta", "Input", "Sorter"];
43
+
44
+ var getSelectedGroup = function getSelectedGroup(groups, model) {
45
+ if (groups.length === 0 || !model) {
46
+ return "";
47
+ }
48
+
49
+ var current = model.group.id;
50
+ var group = groups.find(function (g) {
51
+ return g.value === current;
52
+ });
53
+
54
+ if (group) {
55
+ return group.value;
56
+ }
57
+
58
+ var defaultSelected = groups.find(function () {
59
+ return true;
60
+ });
61
+ return defaultSelected ? defaultSelected.value : group.id;
62
+ };
63
+
64
+ var CloneContentModelDialog = function CloneContentModelDialog(_ref) {
65
+ var open = _ref.open,
66
+ onClose = _ref.onClose,
67
+ contentModel = _ref.contentModel,
68
+ closeModal = _ref.closeModal;
69
+
70
+ var _React$useState = React.useState(false),
71
+ _React$useState2 = _slicedToArray(_React$useState, 2),
72
+ loading = _React$useState2[0],
73
+ setLoading = _React$useState2[1];
74
+
75
+ var _useSnackbar = useSnackbar(),
76
+ showSnackbar = _useSnackbar.showSnackbar;
77
+
78
+ var _useRouter = useRouter(),
79
+ history = _useRouter.history;
80
+
81
+ var _useI18N = useI18N(),
82
+ getLocales = _useI18N.getLocales,
83
+ getCurrentLocale = _useI18N.getCurrentLocale,
84
+ setCurrentLocale = _useI18N.setCurrentLocale;
85
+
86
+ var currentLocale = getCurrentLocale();
87
+
88
+ var _React$useState3 = React.useState(currentLocale),
89
+ _React$useState4 = _slicedToArray(_React$useState3, 2),
90
+ locale = _React$useState4[0],
91
+ setLocale = _React$useState4[1];
92
+
93
+ var _useMutation = useMutation(GQL.CREATE_CONTENT_MODEL_FROM, {
94
+ onError: function onError(error) {
95
+ setLoading(false);
96
+ showSnackbar(error.message);
97
+ },
98
+ update: function update(cache, response) {
99
+ var _response$data$create = response.data.createContentModelFrom,
100
+ model = _response$data$create.data,
101
+ error = _response$data$create.error;
102
+
103
+ if (error) {
104
+ setLoading(false);
105
+ return showSnackbar(error.message);
106
+ }
107
+
108
+ if (currentLocale !== locale) {
109
+ setCurrentLocale(locale, "content");
110
+ window.location.reload();
111
+ return;
112
+ }
113
+
114
+ addModelToListCache(cache, model);
115
+ addModelToGroupCache(cache, model);
116
+ history.push("/cms/content-models/");
117
+ closeModal();
118
+ }
119
+ }),
120
+ _useMutation2 = _slicedToArray(_useMutation, 1),
121
+ createContentModelFrom = _useMutation2[0];
122
+
123
+ var _useQueryLocale = useQueryLocale(GQL.LIST_MENU_CONTENT_GROUPS_MODELS, locale, {
124
+ skip: !open
125
+ }),
126
+ data = _useQueryLocale.data,
127
+ loadingGroups = _useQueryLocale.loading;
128
+
129
+ var contentModelGroups = get(data, "listContentModelGroups.data", []).map(function (item) {
130
+ return {
131
+ value: item.id,
132
+ label: item.name
133
+ };
134
+ });
135
+ var selectedGroup = getSelectedGroup(contentModelGroups, contentModel);
136
+ var nameValidator = useCallback(function (name) {
137
+ var target = (name || "").trim();
138
+
139
+ if (!target.charAt(0).match(/[a-zA-Z]/)) {
140
+ throw new Error("Value is not valid - must not start with a number.");
141
+ }
142
+
143
+ if (target.toLowerCase() === "id") {
144
+ throw new Error('Value is not valid - "id" is an auto-generated field.');
145
+ }
146
+
147
+ var _iterator = _createForOfIteratorHelper(disallowedModelIdEndingList),
148
+ _step;
149
+
150
+ try {
151
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
152
+ var ending = _step.value;
153
+ var re = new RegExp("".concat(ending, "$"), "i");
154
+ var matched = target.match(re);
155
+
156
+ if (matched === null) {
157
+ continue;
158
+ }
159
+
160
+ throw new Error("Model name that ends with \"".concat(ending, "\" is not allowed."));
161
+ }
162
+ } catch (err) {
163
+ _iterator.e(err);
164
+ } finally {
165
+ _iterator.f();
166
+ }
167
+
168
+ return true;
169
+ }, undefined);
170
+ var locales = getLocales().map(function (locale) {
171
+ return {
172
+ value: locale.code,
173
+ label: locale.code === currentLocale ? "Current locale" : locale.code
174
+ };
175
+ });
176
+ return /*#__PURE__*/React.createElement(UID.Dialog, {
177
+ open: open,
178
+ onClose: onClose,
179
+ className: narrowDialog,
180
+ "data-testid": "cms-clone-content-model-modal"
181
+ }, loadingGroups && /*#__PURE__*/React.createElement(CircularProgress, {
182
+ label: "Please wait while we load required information."
183
+ }), open && /*#__PURE__*/React.createElement(Form, {
184
+ data: {
185
+ group: selectedGroup,
186
+ locale: locale,
187
+ name: contentModel.name
188
+ },
189
+ onSubmit: /*#__PURE__*/function () {
190
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(data) {
191
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
192
+ while (1) {
193
+ switch (_context.prev = _context.next) {
194
+ case 0:
195
+ setLoading(true);
196
+ _context.next = 3;
197
+ return createContentModelFrom({
198
+ variables: {
199
+ modelId: contentModel.modelId,
200
+ data: data
201
+ }
202
+ });
203
+
204
+ case 3:
205
+ case "end":
206
+ return _context.stop();
207
+ }
208
+ }
209
+ }, _callee);
210
+ }));
211
+
212
+ return function (_x) {
213
+ return _ref2.apply(this, arguments);
214
+ };
215
+ }()
216
+ }, function (_ref3) {
217
+ var Bind = _ref3.Bind,
218
+ submit = _ref3.submit;
219
+ return /*#__PURE__*/React.createElement(React.Fragment, null, loading && /*#__PURE__*/React.createElement(CircularProgress, null), /*#__PURE__*/React.createElement(UID.DialogTitle, null, t(_templateObject || (_templateObject = _taggedTemplateLiteral(["Clone Content Model"])))), /*#__PURE__*/React.createElement(UID.DialogContent, null, /*#__PURE__*/React.createElement(Grid, {
220
+ className: noPadding
221
+ }, /*#__PURE__*/React.createElement(Cell, {
222
+ span: 12
223
+ }, /*#__PURE__*/React.createElement(Bind, {
224
+ name: "name",
225
+ validators: [validation.create("required,maxLength:100"), nameValidator]
226
+ }, /*#__PURE__*/React.createElement(Input, {
227
+ label: t(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["Name"]))),
228
+ description: t(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["The name of the content model"])))
229
+ }))), /*#__PURE__*/React.createElement(Cell, {
230
+ span: 12
231
+ }, /*#__PURE__*/React.createElement(Bind, {
232
+ name: "group",
233
+ validators: validation.create("required")
234
+ }, /*#__PURE__*/React.createElement(Select, {
235
+ description: t(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["Choose a content model group"]))),
236
+ label: t(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["Content model group"]))),
237
+ options: contentModelGroups
238
+ }))), /*#__PURE__*/React.createElement(Cell, {
239
+ span: 12
240
+ }, /*#__PURE__*/React.createElement(Bind, {
241
+ name: "locale",
242
+ validators: validation.create("required"),
243
+ afterChange: function afterChange(value) {
244
+ if (!value) {
245
+ return;
246
+ }
247
+
248
+ setLocale(value);
249
+ }
250
+ }, /*#__PURE__*/React.createElement(Select, {
251
+ description: t(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["Choose a locale into which you wish to clone the model"]))),
252
+ label: t(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["Content model locale"]))),
253
+ options: locales
254
+ }))), /*#__PURE__*/React.createElement(Cell, {
255
+ span: 12
256
+ }, /*#__PURE__*/React.createElement(Bind, {
257
+ name: "description"
258
+ }, function (props) {
259
+ return /*#__PURE__*/React.createElement(Input, Object.assign({}, props, {
260
+ rows: 4,
261
+ maxLength: 200,
262
+ characterCount: true,
263
+ label: t(_templateObject8 || (_templateObject8 = _taggedTemplateLiteral(["Description"]))),
264
+ value: contentModel.description
265
+ }));
266
+ })))), /*#__PURE__*/React.createElement(UID.DialogActions, null, /*#__PURE__*/React.createElement(ButtonDefault, {
267
+ onClick: submit
268
+ }, "+ ", t(_templateObject9 || (_templateObject9 = _taggedTemplateLiteral(["Clone"]))))));
269
+ }));
270
+ };
271
+
272
+ export default CloneContentModelDialog;
@@ -6,6 +6,7 @@ import ContentModelsDataList from "./ContentModelsDataList";
6
6
  import NewContentModelDialog from "./NewContentModelDialog";
7
7
  import { Cell } from "@webiny/ui/Grid";
8
8
  import { Grid } from "@webiny/ui/Grid";
9
+ import CloneContentModelDialog from "./CloneContentModelDialog";
9
10
  var grid = /*#__PURE__*/css({
10
11
  "&.mdc-layout-grid": {
11
12
  padding: 0,
@@ -39,6 +40,11 @@ function ContentModels() {
39
40
  newContentModelDialogOpened = _React$useState2[0],
40
41
  openNewContentModelDialog = _React$useState2[1];
41
42
 
43
+ var _React$useState3 = React.useState(null),
44
+ _React$useState4 = _slicedToArray(_React$useState3, 2),
45
+ cloneContentModel = _React$useState4[0],
46
+ setCloneContentModel = _React$useState4[1];
47
+
42
48
  var _useSecurity = useSecurity(),
43
49
  identity = _useSecurity.identity;
44
50
 
@@ -55,15 +61,29 @@ function ContentModels() {
55
61
 
56
62
  return permission.rwd.includes("w");
57
63
  }, []);
64
+ var closeModal = useCallback(function () {
65
+ setCloneContentModel(null);
66
+ }, []);
58
67
  var onCreate = useCallback(function () {
59
68
  return openNewContentModelDialog(true);
60
69
  }, []);
61
70
  var onClose = useCallback(function () {
62
71
  return openNewContentModelDialog(false);
63
72
  }, []);
73
+ var onClone = useCallback(function (contentModel) {
74
+ return setCloneContentModel(contentModel);
75
+ }, []);
76
+ var onCloneClose = useCallback(function () {
77
+ return setCloneContentModel(null);
78
+ }, []);
64
79
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(NewContentModelDialog, {
65
80
  open: newContentModelDialogOpened,
66
81
  onClose: onClose
82
+ }), /*#__PURE__*/React.createElement(CloneContentModelDialog, {
83
+ open: !!cloneContentModel,
84
+ contentModel: cloneContentModel,
85
+ onClose: onCloneClose,
86
+ closeModal: closeModal
67
87
  }), /*#__PURE__*/React.createElement(Grid, {
68
88
  className: grid
69
89
  }, /*#__PURE__*/React.createElement(Cell, {
@@ -73,7 +93,8 @@ function ContentModels() {
73
93
  className: centeredContent
74
94
  }, /*#__PURE__*/React.createElement(ContentModelsDataList, {
75
95
  canCreate: canCreate,
76
- onCreate: onCreate
96
+ onCreate: onCreate,
97
+ onClone: onClone
77
98
  })), /*#__PURE__*/React.createElement(Cell, {
78
99
  span: 3
79
100
  })));
@@ -1,7 +1,9 @@
1
1
  /// <reference types="react" />
2
+ import { CmsEditorContentModel } from "../../../types";
2
3
  declare type ContentModelsDataListProps = {
3
4
  canCreate: boolean;
4
5
  onCreate: () => void;
6
+ onClone: (contentModel: CmsEditorContentModel) => void;
5
7
  };
6
- declare const ContentModelsDataList: ({ canCreate, onCreate }: ContentModelsDataListProps) => JSX.Element;
8
+ declare const ContentModelsDataList: ({ canCreate, onCreate, onClone }: ContentModelsDataListProps) => JSX.Element;
7
9
  export default ContentModelsDataList;
@@ -2,7 +2,7 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
2
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
4
4
 
5
- var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13, _templateObject14, _templateObject15, _templateObject16, _templateObject17;
5
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13, _templateObject14, _templateObject15, _templateObject16, _templateObject17, _templateObject18;
6
6
 
7
7
  import _regeneratorRuntime from "@babel/runtime/regenerator";
8
8
  import React, { useCallback, useMemo, useState } from "react";
@@ -12,6 +12,7 @@ import get from "lodash/get";
12
12
  import { useRouter } from "@webiny/react-router";
13
13
  import { DeleteIcon, EditIcon } from "@webiny/ui/List/DataList/icons";
14
14
  import { ReactComponent as ViewListIcon } from "@svgr/webpack!../../icons/view_list.svg";
15
+ import { ReactComponent as CloneIcon } from "@svgr/webpack!../../icons/clone.svg";
15
16
  import { useApolloClient, useQuery } from "../../hooks";
16
17
  import { useSnackbar } from "@webiny/app-admin/hooks/useSnackbar";
17
18
  import * as UIL from "@webiny/ui/List";
@@ -61,7 +62,8 @@ var listItemMinHeight = /*#__PURE__*/css({
61
62
 
62
63
  var ContentModelsDataList = function ContentModelsDataList(_ref) {
63
64
  var canCreate = _ref.canCreate,
64
- onCreate = _ref.onCreate;
65
+ onCreate = _ref.onCreate,
66
+ onClone = _ref.onClone;
65
67
 
66
68
  var _useState = useState(""),
67
69
  _useState2 = _slicedToArray(_useState, 2),
@@ -259,14 +261,24 @@ var ContentModelsDataList = function ContentModelsDataList(_ref) {
259
261
  return editRecord(contentModel);
260
262
  },
261
263
  "data-testid": "cms-edit-content-model-button"
262
- }))), canDelete(contentModel, "cms.contentModel") && contentModel.plugin ? /*#__PURE__*/React.createElement(Tooltip, {
263
- content: t(_templateObject16 || (_templateObject16 = _taggedTemplateLiteral(["Content model is registered via a plugin."]))),
264
+ }))), /*#__PURE__*/React.createElement(Tooltip, {
265
+ content: "Clone content model",
266
+ placement: "top"
267
+ }, /*#__PURE__*/React.createElement(IconButton, {
268
+ "data-testid": "cms-clone-content-model-button",
269
+ icon: /*#__PURE__*/React.createElement(CloneIcon, null),
270
+ label: t(_templateObject16 || (_templateObject16 = _taggedTemplateLiteral(["View entries"]))),
271
+ onClick: function onClick() {
272
+ return onClone(contentModel);
273
+ }
274
+ })), canDelete(contentModel, "cms.contentModel") && contentModel.plugin ? /*#__PURE__*/React.createElement(Tooltip, {
275
+ content: t(_templateObject17 || (_templateObject17 = _taggedTemplateLiteral(["Content model is registered via a plugin."]))),
264
276
  placement: "top"
265
277
  }, /*#__PURE__*/React.createElement(DeleteIcon, {
266
278
  disabled: true,
267
279
  "data-testid": "cms-delete-content-model-button"
268
280
  })) : /*#__PURE__*/React.createElement(Tooltip, {
269
- content: t(_templateObject17 || (_templateObject17 = _taggedTemplateLiteral(["Delete content model"]))),
281
+ content: t(_templateObject18 || (_templateObject18 = _taggedTemplateLiteral(["Delete content model"]))),
270
282
  placement: "top"
271
283
  }, /*#__PURE__*/React.createElement(DeleteIcon, {
272
284
  onClick: function onClick() {
@@ -63,6 +63,7 @@ var NewContentModelDialog = function NewContentModelDialog(_ref) {
63
63
  error = _data$createContentMo.error;
64
64
 
65
65
  if (error) {
66
+ setLoading(false);
66
67
  return showSnackbar(error.message);
67
68
  }
68
69
 
@@ -1,4 +1,5 @@
1
1
  export declare const LIST_MENU_CONTENT_GROUPS_MODELS: import("graphql").DocumentNode;
2
2
  export declare const LIST_CONTENT_MODELS: import("graphql").DocumentNode;
3
3
  export declare const CREATE_CONTENT_MODEL: import("graphql").DocumentNode;
4
+ export declare const CREATE_CONTENT_MODEL_FROM: import("graphql").DocumentNode;
4
5
  export declare const DELETE_CONTENT_MODEL: import("graphql").DocumentNode;
@@ -1,6 +1,6 @@
1
1
  import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
2
 
3
- var _templateObject, _templateObject2, _templateObject3, _templateObject4;
3
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5;
4
4
 
5
5
  import gql from "graphql-tag";
6
6
  var ERROR_FIELDS = "\n code\n message\n data\n";
@@ -9,4 +9,5 @@ var BASE_CONTENT_MODEL_FIELDS = "\n description\n modelId\n name\n s
9
9
  export var LIST_MENU_CONTENT_GROUPS_MODELS = gql(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n query CmsListMenuContentGroupsModels {\n listContentModelGroups {\n data {\n id\n name\n icon\n plugin\n contentModels {\n name\n modelId\n plugin\n createdBy {\n id\n displayName\n type\n }\n }\n }\n }\n }\n"])));
10
10
  export var LIST_CONTENT_MODELS = gql(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n query CmsListContentModels {\n listContentModels {\n data {\n ", "\n }\n }\n }\n"])), BASE_CONTENT_MODEL_FIELDS);
11
11
  export var CREATE_CONTENT_MODEL = gql(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n mutation CmsCreateContentModel($data: CmsContentModelCreateInput!) {\n createContentModel(data: $data) {\n data {\n ", "\n }\n error {\n message\n data\n }\n }\n }\n"])), BASE_CONTENT_MODEL_FIELDS);
12
- export var DELETE_CONTENT_MODEL = gql(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n mutation CmsDeleteContentModel($modelId: ID!) {\n deleteContentModel(modelId: $modelId) {\n data\n error {\n ", "\n }\n }\n }\n"])), ERROR_FIELDS);
12
+ export var CREATE_CONTENT_MODEL_FROM = gql(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n mutation CmsCreateContentModelFrom($modelId: ID!, $data: CmsContentModelCreateFromInput!) {\n createContentModelFrom(modelId: $modelId, data: $data) {\n data {\n ", "\n }\n error {\n message\n data\n }\n }\n }\n"])), BASE_CONTENT_MODEL_FIELDS);
13
+ export var DELETE_CONTENT_MODEL = gql(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n mutation CmsDeleteContentModel($modelId: ID!) {\n deleteContentModel(modelId: $modelId) {\n data\n error {\n ", "\n }\n }\n }\n"])), ERROR_FIELDS);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/app-headless-cms",
3
- "version": "5.19.1-beta.0",
3
+ "version": "5.20.0-beta.2",
4
4
  "main": "index.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,19 +24,19 @@
24
24
  "@fortawesome/react-fontawesome": "0.1.16",
25
25
  "@svgr/webpack": "4.3.3",
26
26
  "@types/react": "16.14.2",
27
- "@webiny/app": "5.19.1-beta.0",
28
- "@webiny/app-admin": "5.19.1-beta.0",
29
- "@webiny/app-graphql-playground": "5.19.1-beta.0",
30
- "@webiny/app-i18n": "5.19.1-beta.0",
31
- "@webiny/app-plugin-admin-welcome-screen": "5.19.1-beta.0",
32
- "@webiny/app-security": "5.19.1-beta.0",
33
- "@webiny/error": "5.19.1-beta.0",
34
- "@webiny/form": "5.19.1-beta.0",
35
- "@webiny/plugins": "5.19.1-beta.0",
36
- "@webiny/react-router": "5.19.1-beta.0",
37
- "@webiny/ui": "5.19.1-beta.0",
38
- "@webiny/utils": "5.19.1-beta.0",
39
- "@webiny/validation": "5.19.1-beta.0",
27
+ "@webiny/app": "5.20.0-beta.2",
28
+ "@webiny/app-admin": "5.20.0-beta.2",
29
+ "@webiny/app-graphql-playground": "5.20.0-beta.2",
30
+ "@webiny/app-i18n": "5.20.0-beta.2",
31
+ "@webiny/app-plugin-admin-welcome-screen": "5.20.0-beta.2",
32
+ "@webiny/app-security": "5.20.0-beta.2",
33
+ "@webiny/error": "5.20.0-beta.2",
34
+ "@webiny/form": "5.20.0-beta.2",
35
+ "@webiny/plugins": "5.20.0-beta.2",
36
+ "@webiny/react-router": "5.20.0-beta.2",
37
+ "@webiny/ui": "5.20.0-beta.2",
38
+ "@webiny/utils": "5.20.0-beta.2",
39
+ "@webiny/validation": "5.20.0-beta.2",
40
40
  "apollo-cache": "1.3.5",
41
41
  "apollo-client": "2.6.10",
42
42
  "apollo-link": "1.2.14",
@@ -68,8 +68,8 @@
68
68
  "@babel/preset-env": "^7.5.5",
69
69
  "@babel/preset-react": "^7.0.0",
70
70
  "@babel/preset-typescript": "^7.8.3",
71
- "@webiny/cli": "^5.19.1-beta.0",
72
- "@webiny/project-utils": "^5.19.1-beta.0",
71
+ "@webiny/cli": "^5.20.0-beta.2",
72
+ "@webiny/project-utils": "^5.20.0-beta.2",
73
73
  "babel-plugin-emotion": "^9.2.8",
74
74
  "babel-plugin-lodash": "^3.3.4",
75
75
  "babel-plugin-module-resolver": "^4.1.0",
@@ -107,5 +107,5 @@
107
107
  ]
108
108
  }
109
109
  },
110
- "gitHead": "c217ea1361f1d1536c6c4ee577579e1faca240eb"
110
+ "gitHead": "86c73ea3b5bf71372f255aa24ee8c6ed98466b7f"
111
111
  }