@webiny/app-file-manager 6.1.0-beta.0 → 6.1.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.
Files changed (31) hide show
  1. package/package.json +18 -21
  2. package/components/ImageEditor/ImageEditor.d.ts +0 -45
  3. package/components/ImageEditor/ImageEditor.js +0 -214
  4. package/components/ImageEditor/ImageEditor.js.map +0 -1
  5. package/components/ImageEditor/ImageEditorDialog.d.ts +0 -16
  6. package/components/ImageEditor/ImageEditorDialog.js +0 -53
  7. package/components/ImageEditor/ImageEditorDialog.js.map +0 -1
  8. package/components/ImageEditor/index.d.ts +0 -1
  9. package/components/ImageEditor/index.js +0 -3
  10. package/components/ImageEditor/index.js.map +0 -1
  11. package/components/ImageEditor/toolbar/crop.d.ts +0 -4
  12. package/components/ImageEditor/toolbar/crop.js +0 -67
  13. package/components/ImageEditor/toolbar/crop.js.map +0 -1
  14. package/components/ImageEditor/toolbar/filter.d.ts +0 -3
  15. package/components/ImageEditor/toolbar/filter.js +0 -167
  16. package/components/ImageEditor/toolbar/filter.js.map +0 -1
  17. package/components/ImageEditor/toolbar/flip.d.ts +0 -4
  18. package/components/ImageEditor/toolbar/flip.js +0 -94
  19. package/components/ImageEditor/toolbar/flip.js.map +0 -1
  20. package/components/ImageEditor/toolbar/index.d.ts +0 -4
  21. package/components/ImageEditor/toolbar/index.js +0 -6
  22. package/components/ImageEditor/toolbar/index.js.map +0 -1
  23. package/components/ImageEditor/toolbar/rotate.d.ts +0 -4
  24. package/components/ImageEditor/toolbar/rotate.js +0 -93
  25. package/components/ImageEditor/toolbar/rotate.js.map +0 -1
  26. package/components/ImageEditor/toolbar/types.d.ts +0 -32
  27. package/components/ImageEditor/toolbar/types.js +0 -3
  28. package/components/ImageEditor/toolbar/types.js.map +0 -1
  29. package/modules/FileManagerRenderer/FileActions/FileDetails/EditImage.d.ts +0 -2
  30. package/modules/FileManagerRenderer/FileActions/FileDetails/EditImage.js +0 -106
  31. package/modules/FileManagerRenderer/FileActions/FileDetails/EditImage.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/app-file-manager",
3
- "version": "6.1.0-beta.0",
3
+ "version": "6.1.0-beta.2",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -14,33 +14,30 @@
14
14
  "@apollo/react-components": "3.1.5",
15
15
  "@apollo/react-hooks": "3.1.5",
16
16
  "@types/react": "18.2.79",
17
- "@webiny/admin-ui": "6.1.0-beta.0",
18
- "@webiny/app": "6.1.0-beta.0",
19
- "@webiny/app-aco": "6.1.0-beta.0",
20
- "@webiny/app-admin": "6.1.0-beta.0",
21
- "@webiny/app-headless-cms": "6.1.0-beta.0",
22
- "@webiny/app-headless-cms-common": "6.1.0-beta.0",
23
- "@webiny/app-websockets": "6.1.0-beta.0",
24
- "@webiny/error": "6.1.0-beta.0",
25
- "@webiny/form": "6.1.0-beta.0",
26
- "@webiny/icons": "6.1.0-beta.0",
27
- "@webiny/plugins": "6.1.0-beta.0",
28
- "@webiny/react-composition": "6.1.0-beta.0",
29
- "@webiny/react-properties": "6.1.0-beta.0",
30
- "@webiny/utils": "6.1.0-beta.0",
31
- "@webiny/validation": "6.1.0-beta.0",
17
+ "@webiny/admin-ui": "6.1.0-beta.2",
18
+ "@webiny/app": "6.1.0-beta.2",
19
+ "@webiny/app-aco": "6.1.0-beta.2",
20
+ "@webiny/app-admin": "6.1.0-beta.2",
21
+ "@webiny/app-headless-cms": "6.1.0-beta.2",
22
+ "@webiny/app-headless-cms-common": "6.1.0-beta.2",
23
+ "@webiny/app-websockets": "6.1.0-beta.2",
24
+ "@webiny/error": "6.1.0-beta.2",
25
+ "@webiny/form": "6.1.0-beta.2",
26
+ "@webiny/icons": "6.1.0-beta.2",
27
+ "@webiny/plugins": "6.1.0-beta.2",
28
+ "@webiny/react-composition": "6.1.0-beta.2",
29
+ "@webiny/react-properties": "6.1.0-beta.2",
30
+ "@webiny/utils": "6.1.0-beta.2",
31
+ "@webiny/validation": "6.1.0-beta.2",
32
32
  "apollo-cache": "1.3.5",
33
33
  "apollo-client": "2.6.10",
34
34
  "apollo-link": "1.2.14",
35
35
  "apollo-utilities": "1.3.4",
36
36
  "bytes": "3.1.2",
37
- "cropperjs": "1.6.2",
38
- "dataurl-to-blob": "0.0.1",
39
37
  "dayjs": "1.11.20",
40
38
  "dot-prop-immutable": "2.1.1",
41
39
  "graphql": "16.13.2",
42
40
  "graphql-tag": "2.12.6",
43
- "load-script": "2.0.0",
44
41
  "lodash": "4.17.23",
45
42
  "mime": "4.1.0",
46
43
  "minimatch": "10.2.4",
@@ -56,7 +53,7 @@
56
53
  },
57
54
  "devDependencies": {
58
55
  "@svgr/webpack": "8.1.0",
59
- "@webiny/build-tools": "6.1.0-beta.0",
56
+ "@webiny/build-tools": "6.1.0-beta.2",
60
57
  "rimraf": "6.1.3",
61
58
  "typescript": "5.9.3",
62
59
  "vitest": "4.1.2"
@@ -65,5 +62,5 @@
65
62
  "access": "public",
66
63
  "directory": "dist"
67
64
  },
68
- "gitHead": "a3bd3695c66c79238e380d7360d9731b5fcf9c87"
65
+ "gitHead": "7174b414a55fc1c3f4cf38abab69dba5109e7765"
69
66
  }
@@ -1,45 +0,0 @@
1
- import React from "react";
2
- import type { ImageEditorTool, ToolbarTool } from "./toolbar/types.js";
3
- interface RenderPropArgs {
4
- render: () => React.ReactNode;
5
- getCanvasDataUrl: () => string;
6
- activeTool: ImageEditorTool | null;
7
- applyActiveTool: () => Promise<void>;
8
- cancelActiveTool: () => Promise<void>;
9
- }
10
- interface ImageEditorPropsPropsOptions {
11
- autoEnable: boolean;
12
- }
13
- interface ImageEditorProps {
14
- src: string;
15
- tools: ToolbarTool[];
16
- options?: {
17
- flip: ImageEditorPropsPropsOptions;
18
- filter: ImageEditorPropsPropsOptions;
19
- crop: ImageEditorPropsPropsOptions;
20
- rotate: ImageEditorPropsPropsOptions;
21
- };
22
- onToolActivate?: () => void;
23
- onToolDeactivate?: () => void;
24
- children?: (props: RenderPropArgs) => React.ReactNode;
25
- }
26
- interface ImageEditorState {
27
- tool: ImageEditorTool | null;
28
- src: string;
29
- }
30
- declare class ImageEditor extends React.Component<ImageEditorProps, ImageEditorState> {
31
- static defaultProps: Partial<ImageEditorProps>;
32
- state: ImageEditorState;
33
- canvas: React.RefObject<HTMLCanvasElement>;
34
- image?: HTMLImageElement;
35
- componentDidMount(): void;
36
- private readonly updateCanvas;
37
- private readonly activateTool;
38
- private readonly deactivateTool;
39
- readonly getCanvasDataUrl: () => string;
40
- private readonly applyActiveTool;
41
- private readonly cancelActiveTool;
42
- private readonly getToolOptions;
43
- render(): React.ReactNode;
44
- }
45
- export { ImageEditor };
@@ -1,214 +0,0 @@
1
- import React from "react";
2
- import { Button } from "@webiny/admin-ui";
3
- import { flip, filter, crop, rotate } from "./toolbar/index.js";
4
- import loadScript from "load-script";
5
- const toolbar = {
6
- flip,
7
- filter,
8
- crop,
9
- rotate
10
- };
11
- const initScripts = () => {
12
- return new Promise(resolve => {
13
- // @ts-expect-error
14
- if (window.Caman) {
15
- return resolve();
16
- }
17
- return loadScript("https://cdnjs.cloudflare.com/ajax/libs/camanjs/4.1.2/caman.full.min.js", resolve);
18
- });
19
- };
20
- class ImageEditor extends React.Component {
21
- static defaultProps = {
22
- tools: ["crop", "flip", "rotate", "filter"]
23
- };
24
- state = {
25
- tool: null,
26
- src: ""
27
- };
28
- canvas = /*#__PURE__*/React.createRef();
29
- componentDidMount() {
30
- initScripts().then(() => {
31
- this.updateCanvas();
32
- setTimeout(() => {
33
- const {
34
- options
35
- } = this.props;
36
- if (!options || typeof options !== "object") {
37
- return;
38
- }
39
- for (const key in options) {
40
- const option = options[key];
41
- if (option.autoEnable === true) {
42
- const tool = toolbar[key];
43
- tool && this.activateTool(tool);
44
- break;
45
- }
46
- }
47
- }, 250);
48
- });
49
- }
50
- updateCanvas = () => {
51
- const {
52
- src
53
- } = this.props;
54
- this.image = new window.Image();
55
- const canvas = this.canvas.current;
56
- if (canvas) {
57
- this.image.onload = () => {
58
- if (this.image) {
59
- canvas.width = this.image.width;
60
- canvas.height = this.image.height;
61
- const ctx = canvas.getContext("2d");
62
- ctx.drawImage(this.image, 0, 0);
63
- }
64
- };
65
- this.image.src = src;
66
- }
67
- };
68
- activateTool = tool => {
69
- if (typeof tool === "string") {
70
- tool = toolbar[tool];
71
- }
72
- this.setState({
73
- tool
74
- }, () => {
75
- const tt = tool;
76
- typeof tt.onActivate === "function" && tt.onActivate({
77
- canvas: this.canvas,
78
- options: this.getToolOptions(tt)
79
- });
80
- });
81
- };
82
- deactivateTool = () => {
83
- this.setState({
84
- tool: null
85
- });
86
- };
87
- getCanvasDataUrl = () => {
88
- const canvas = this.canvas.current;
89
- if (canvas) {
90
- const {
91
- src
92
- } = this.props;
93
- if (src.startsWith("data:image/jpeg;")) {
94
- return canvas.toDataURL("image/jpeg", 1.0);
95
- }
96
- return canvas.toDataURL();
97
- }
98
- return "";
99
- };
100
- applyActiveTool = async () => {
101
- const {
102
- tool
103
- } = this.state;
104
- if (!tool) {
105
- return;
106
- }
107
- if (tool.apply) {
108
- await tool.apply({
109
- canvas: this.canvas
110
- });
111
- }
112
- this.deactivateTool();
113
- };
114
- cancelActiveTool = async () => {
115
- const {
116
- tool
117
- } = this.state;
118
- if (!tool) {
119
- return;
120
- }
121
- if (tool.cancel) {
122
- await tool.cancel({
123
- canvas: this.canvas
124
- });
125
- }
126
- this.deactivateTool();
127
- };
128
- getToolOptions = tool => {
129
- const {
130
- options
131
- } = this.props;
132
- if (!options || typeof options !== "object") {
133
- return {};
134
- }
135
- return options[tool.name] || {};
136
- };
137
- render() {
138
- const {
139
- src,
140
- tools,
141
- children
142
- } = this.props;
143
- const {
144
- tool
145
- } = this.state;
146
- const editor = /*#__PURE__*/React.createElement("div", {
147
- className: "w-full h-full flex flex-col gap-md overflow-hidden"
148
- }, /*#__PURE__*/React.createElement("div", {
149
- className: "flex justify-center items-center w-full"
150
- }, tools.map(key => {
151
- const tool = toolbar[key];
152
- if (!tool) {
153
- return null;
154
- }
155
- return /*#__PURE__*/React.createElement("div", {
156
- key: key,
157
- className: this.state.tool ? "opacity-50 cursor pointer-events-none" : ""
158
- }, tool.icon({
159
- activateTool: () => this.activateTool(tool)
160
- }));
161
- })), /*#__PURE__*/React.createElement("div", {
162
- className: "w-full"
163
- }, tool ? /*#__PURE__*/React.createElement(React.Fragment, null, typeof tool.renderForm === "function" && tool.renderForm({
164
- options: this.getToolOptions(tool),
165
- image: this.image,
166
- canvas: this.canvas
167
- }), /*#__PURE__*/React.createElement("div", {
168
- className: "flex justify-center gap-sm mt-sm"
169
- }, /*#__PURE__*/React.createElement(Button, {
170
- variant: "secondary",
171
- text: "Cancel",
172
- "data-testid": "button-cancel",
173
- onClick: () => {
174
- this.cancelActiveTool();
175
- }
176
- }), /*#__PURE__*/React.createElement(Button, {
177
- variant: "primary",
178
- text: "Apply",
179
- "data-testid": "button-apply",
180
- onClick: () => {
181
- this.applyActiveTool();
182
- }
183
- }))) : /*#__PURE__*/React.createElement("div", {
184
- className: "text-center"
185
- }, "Select a tool to start working on your image.")), /*#__PURE__*/React.createElement("div", {
186
- className: "flex justify-center items-center w-full bg-neutral-dimmed rounded-md overflow-hidden",
187
- style: {
188
- height: "calc(100vh - 256px)"
189
- }
190
- }, /*#__PURE__*/React.createElement("canvas", {
191
- key: src,
192
- id: "canvas",
193
- style: {
194
- maxWidth: "100%",
195
- maxHeight: "100%"
196
- },
197
- ref: this.canvas
198
- })));
199
- if (typeof children === "function") {
200
- return children({
201
- render: () => editor,
202
- // canvas: this.canvas,
203
- getCanvasDataUrl: this.getCanvasDataUrl,
204
- activeTool: this.state.tool,
205
- applyActiveTool: this.applyActiveTool,
206
- cancelActiveTool: this.cancelActiveTool
207
- });
208
- }
209
- return editor;
210
- }
211
- }
212
- export { ImageEditor };
213
-
214
- //# sourceMappingURL=ImageEditor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","Button","flip","filter","crop","rotate","loadScript","toolbar","initScripts","Promise","resolve","window","Caman","ImageEditor","Component","defaultProps","tools","state","tool","src","canvas","createRef","componentDidMount","then","updateCanvas","setTimeout","options","props","key","option","autoEnable","activateTool","image","Image","current","onload","width","height","ctx","getContext","drawImage","setState","tt","onActivate","getToolOptions","deactivateTool","getCanvasDataUrl","startsWith","toDataURL","applyActiveTool","apply","cancelActiveTool","cancel","name","render","children","editor","createElement","className","map","icon","Fragment","renderForm","variant","text","onClick","style","id","maxWidth","maxHeight","ref","activeTool"],"sources":["ImageEditor.tsx"],"sourcesContent":["import React from \"react\";\nimport { Button } from \"@webiny/admin-ui\";\nimport { flip, filter, crop, rotate } from \"./toolbar/index.js\";\nimport type { ImageEditorTool, ToolbarTool } from \"./toolbar/types.js\";\nimport loadScript from \"load-script\";\n\nconst toolbar = {\n flip,\n filter,\n crop,\n rotate\n};\n\nconst initScripts = (): Promise<string> => {\n return new Promise((resolve: any) => {\n // @ts-expect-error\n if (window.Caman) {\n return resolve();\n }\n return loadScript(\n \"https://cdnjs.cloudflare.com/ajax/libs/camanjs/4.1.2/caman.full.min.js\",\n resolve\n );\n });\n};\n\ninterface RenderPropArgs {\n render: () => React.ReactNode;\n getCanvasDataUrl: () => string;\n activeTool: ImageEditorTool | null;\n applyActiveTool: () => Promise<void>;\n cancelActiveTool: () => Promise<void>;\n}\n\ninterface ImageEditorPropsPropsOptions {\n autoEnable: boolean;\n}\n\ninterface ImageEditorProps {\n src: string;\n tools: ToolbarTool[];\n options?: {\n flip: ImageEditorPropsPropsOptions;\n filter: ImageEditorPropsPropsOptions;\n crop: ImageEditorPropsPropsOptions;\n rotate: ImageEditorPropsPropsOptions;\n };\n onToolActivate?: () => void;\n onToolDeactivate?: () => void;\n children?: (props: RenderPropArgs) => React.ReactNode;\n}\n\ninterface ImageEditorState {\n tool: ImageEditorTool | null;\n src: string;\n}\n\nclass ImageEditor extends React.Component<ImageEditorProps, ImageEditorState> {\n static defaultProps: Partial<ImageEditorProps> = {\n tools: [\"crop\", \"flip\", \"rotate\", \"filter\"]\n };\n\n public override state: ImageEditorState = {\n tool: null,\n src: \"\"\n };\n\n public canvas = React.createRef<HTMLCanvasElement>();\n public image?: HTMLImageElement;\n\n public override componentDidMount() {\n initScripts().then(() => {\n this.updateCanvas();\n setTimeout(() => {\n const { options } = this.props;\n if (!options || typeof options !== \"object\") {\n return;\n }\n for (const key in options) {\n const option = options[key as ToolbarTool];\n if (option.autoEnable === true) {\n const tool: ImageEditorTool | null = toolbar[key as ToolbarTool];\n tool && this.activateTool(tool);\n break;\n }\n }\n }, 250);\n });\n }\n\n private readonly updateCanvas = (): void => {\n const { src } = this.props;\n this.image = new window.Image();\n const canvas = this.canvas.current;\n if (canvas) {\n this.image.onload = () => {\n if (this.image) {\n canvas.width = this.image.width;\n canvas.height = this.image.height;\n const ctx = canvas.getContext(\"2d\") as CanvasRenderingContext2D;\n ctx.drawImage(this.image, 0, 0);\n }\n };\n\n this.image.src = src;\n }\n };\n\n private readonly activateTool = (tool: ToolbarTool | ImageEditorTool): void => {\n if (typeof tool === \"string\") {\n tool = toolbar[tool];\n }\n\n this.setState({ tool }, () => {\n const tt = tool as ImageEditorTool;\n typeof tt.onActivate === \"function\" &&\n tt.onActivate({ canvas: this.canvas, options: this.getToolOptions(tt) });\n });\n };\n\n private readonly deactivateTool = (): void => {\n this.setState({\n tool: null\n });\n };\n\n public readonly getCanvasDataUrl = (): string => {\n const canvas = this.canvas.current as HTMLCanvasElement;\n if (canvas) {\n const { src } = this.props;\n if (src.startsWith(\"data:image/jpeg;\")) {\n return canvas.toDataURL(\"image/jpeg\", 1.0);\n }\n\n return canvas.toDataURL();\n }\n\n return \"\";\n };\n\n private readonly applyActiveTool = async (): Promise<void> => {\n const { tool } = this.state;\n if (!tool) {\n return;\n }\n\n if (tool.apply) {\n await tool.apply({\n canvas: this.canvas\n });\n }\n this.deactivateTool();\n };\n\n private readonly cancelActiveTool = async (): Promise<void> => {\n const { tool } = this.state;\n if (!tool) {\n return;\n }\n\n if (tool.cancel) {\n await tool.cancel({\n canvas: this.canvas\n });\n }\n this.deactivateTool();\n };\n\n private readonly getToolOptions = (\n tool: ImageEditorTool\n ): Partial<ImageEditorPropsPropsOptions> => {\n const { options } = this.props;\n if (!options || typeof options !== \"object\") {\n return {};\n }\n\n return options[tool.name as ToolbarTool] || {};\n };\n\n public override render(): React.ReactNode {\n const { src, tools, children } = this.props;\n const { tool } = this.state;\n const editor = (\n <div className={\"w-full h-full flex flex-col gap-md overflow-hidden\"}>\n <div className={\"flex justify-center items-center w-full\"}>\n {tools.map(key => {\n const tool: ImageEditorTool = toolbar[key];\n if (!tool) {\n return null;\n }\n\n return (\n <div\n key={key}\n className={\n this.state.tool ? \"opacity-50 cursor pointer-events-none\" : \"\"\n }\n >\n {tool.icon({\n activateTool: () => this.activateTool(tool)\n })}\n </div>\n );\n })}\n </div>\n <div className={\"w-full\"}>\n {tool ? (\n <>\n {typeof tool.renderForm === \"function\" &&\n tool.renderForm({\n options: this.getToolOptions(tool as ImageEditorTool),\n image: this.image as HTMLImageElement,\n canvas: this.canvas\n })}\n\n <div className={\"flex justify-center gap-sm mt-sm\"}>\n <Button\n variant={\"secondary\"}\n text={\"Cancel\"}\n data-testid=\"button-cancel\"\n onClick={() => {\n this.cancelActiveTool();\n }}\n />\n <Button\n variant={\"primary\"}\n text={\"Apply\"}\n data-testid=\"button-apply\"\n onClick={() => {\n this.applyActiveTool();\n }}\n />\n </div>\n </>\n ) : (\n <div className={\"text-center\"}>\n Select a tool to start working on your image.\n </div>\n )}\n </div>\n <div\n className={\n \"flex justify-center items-center w-full bg-neutral-dimmed rounded-md overflow-hidden\"\n }\n style={{ height: \"calc(100vh - 256px)\" }}\n >\n <canvas\n key={src}\n id={\"canvas\"}\n style={{ maxWidth: \"100%\", maxHeight: \"100%\" }}\n ref={this.canvas as React.Ref<any>}\n />\n </div>\n </div>\n );\n\n if (typeof children === \"function\") {\n return children({\n render: () => editor,\n // canvas: this.canvas,\n getCanvasDataUrl: this.getCanvasDataUrl,\n activeTool: this.state.tool,\n applyActiveTool: this.applyActiveTool,\n cancelActiveTool: this.cancelActiveTool\n });\n }\n\n return editor;\n }\n}\n\nexport { ImageEditor };\n"],"mappings":"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","ignoreList":[]}
@@ -1,16 +0,0 @@
1
- import React from "react";
2
- interface ImageEditorDialogProps {
3
- dialogZIndex?: number;
4
- onClose?: () => void;
5
- open?: boolean;
6
- /**
7
- * We would need to drill down a lot to give correct options.
8
- * TODO: figure out some other way.
9
- */
10
- options?: any;
11
- src?: string;
12
- onAccept: (src: string) => void;
13
- "data-testid"?: string;
14
- }
15
- export declare const ImageEditorDialog: (props: ImageEditorDialogProps) => React.JSX.Element;
16
- export {};
@@ -1,53 +0,0 @@
1
- import React, { useState } from "react";
2
- import { ImageEditor } from "./ImageEditor.js";
3
- import { Dialog, OverlayLoader } from "@webiny/admin-ui";
4
- export const ImageEditorDialog = props => {
5
- const {
6
- src,
7
- options,
8
- onAccept,
9
- onClose,
10
- open,
11
- dialogZIndex,
12
- ...dialogProps
13
- } = props;
14
- const imageEditor = /*#__PURE__*/React.createRef();
15
- const [isSaving, setIsSaving] = useState(false);
16
- const onSave = async () => {
17
- try {
18
- setIsSaving(true);
19
- const url = imageEditor.current ? imageEditor.current.getCanvasDataUrl() : "";
20
- await onAccept(url);
21
- } catch (e) {
22
- console.log(e);
23
- } finally {
24
- setIsSaving(false);
25
- }
26
- };
27
- return /*#__PURE__*/React.createElement(Dialog, Object.assign({
28
- style: {
29
- zIndex: dialogZIndex
30
- },
31
- title: "Edit Image",
32
- size: "full",
33
- open: open,
34
- onClose: onClose
35
- }, dialogProps, {
36
- actions: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Dialog.CancelAction, null), /*#__PURE__*/React.createElement(Dialog.ConfirmAction, {
37
- text: "Save",
38
- "data-testid": "dialog-accept",
39
- onClick: onSave,
40
- disabled: isSaving
41
- }))
42
- }), isSaving && /*#__PURE__*/React.createElement(OverlayLoader, {
43
- text: "Creating a new version of the image"
44
- }), /*#__PURE__*/React.createElement(ImageEditor, {
45
- ref: imageEditor,
46
- src: src,
47
- options: options
48
- }, ({
49
- render
50
- }) => render()));
51
- };
52
-
53
- //# sourceMappingURL=ImageEditorDialog.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","useState","ImageEditor","Dialog","OverlayLoader","ImageEditorDialog","props","src","options","onAccept","onClose","open","dialogZIndex","dialogProps","imageEditor","createRef","isSaving","setIsSaving","onSave","url","current","getCanvasDataUrl","e","console","log","createElement","Object","assign","style","zIndex","title","size","actions","Fragment","CancelAction","ConfirmAction","text","onClick","disabled","ref","render"],"sources":["ImageEditorDialog.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport { ImageEditor } from \"./ImageEditor.js\";\nimport { Dialog, OverlayLoader } from \"@webiny/admin-ui\";\n\ninterface ImageEditorDialogProps {\n dialogZIndex?: number;\n onClose?: () => void;\n open?: boolean;\n /**\n * We would need to drill down a lot to give correct options.\n * TODO: figure out some other way.\n */\n options?: any;\n src?: string;\n onAccept: (src: string) => void;\n \"data-testid\"?: string;\n}\n\nexport const ImageEditorDialog = (props: ImageEditorDialogProps) => {\n const { src, options, onAccept, onClose, open, dialogZIndex, ...dialogProps } = props;\n const imageEditor = React.createRef<ImageEditor>();\n const [isSaving, setIsSaving] = useState(false);\n\n const onSave = async () => {\n try {\n setIsSaving(true);\n const url = imageEditor.current ? imageEditor.current.getCanvasDataUrl() : \"\";\n await onAccept(url);\n } catch (e) {\n console.log(e);\n } finally {\n setIsSaving(false);\n }\n };\n\n return (\n <Dialog\n style={{ zIndex: dialogZIndex }}\n title={\"Edit Image\"}\n size={\"full\"}\n open={open}\n onClose={onClose}\n {...dialogProps}\n actions={\n <>\n <Dialog.CancelAction />\n <Dialog.ConfirmAction\n text={\"Save\"}\n data-testid=\"dialog-accept\"\n onClick={onSave}\n disabled={isSaving}\n />\n </>\n }\n >\n {isSaving && <OverlayLoader text={\"Creating a new version of the image\"} />}\n <ImageEditor ref={imageEditor} src={src} options={options}>\n {({ render }) => render()}\n </ImageEditor>\n </Dialog>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,QAAQ,QAAQ,OAAO;AACvC,SAASC,WAAW;AACpB,SAASC,MAAM,EAAEC,aAAa,QAAQ,kBAAkB;AAgBxD,OAAO,MAAMC,iBAAiB,GAAIC,KAA6B,IAAK;EAChE,MAAM;IAAEC,GAAG;IAAEC,OAAO;IAAEC,QAAQ;IAAEC,OAAO;IAAEC,IAAI;IAAEC,YAAY;IAAE,GAAGC;EAAY,CAAC,GAAGP,KAAK;EACrF,MAAMQ,WAAW,gBAAGd,KAAK,CAACe,SAAS,CAAc,CAAC;EAClD,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGhB,QAAQ,CAAC,KAAK,CAAC;EAE/C,MAAMiB,MAAM,GAAG,MAAAA,CAAA,KAAY;IACvB,IAAI;MACAD,WAAW,CAAC,IAAI,CAAC;MACjB,MAAME,GAAG,GAAGL,WAAW,CAACM,OAAO,GAAGN,WAAW,CAACM,OAAO,CAACC,gBAAgB,CAAC,CAAC,GAAG,EAAE;MAC7E,MAAMZ,QAAQ,CAACU,GAAG,CAAC;IACvB,CAAC,CAAC,OAAOG,CAAC,EAAE;MACRC,OAAO,CAACC,GAAG,CAACF,CAAC,CAAC;IAClB,CAAC,SAAS;MACNL,WAAW,CAAC,KAAK,CAAC;IACtB;EACJ,CAAC;EAED,oBACIjB,KAAA,CAAAyB,aAAA,CAACtB,MAAM,EAAAuB,MAAA,CAAAC,MAAA;IACHC,KAAK,EAAE;MAAEC,MAAM,EAAEjB;IAAa,CAAE;IAChCkB,KAAK,EAAE,YAAa;IACpBC,IAAI,EAAE,MAAO;IACbpB,IAAI,EAAEA,IAAK;IACXD,OAAO,EAAEA;EAAQ,GACbG,WAAW;IACfmB,OAAO,eACHhC,KAAA,CAAAyB,aAAA,CAAAzB,KAAA,CAAAiC,QAAA,qBACIjC,KAAA,CAAAyB,aAAA,CAACtB,MAAM,CAAC+B,YAAY,MAAE,CAAC,eACvBlC,KAAA,CAAAyB,aAAA,CAACtB,MAAM,CAACgC,aAAa;MACjBC,IAAI,EAAE,MAAO;MACb,eAAY,eAAe;MAC3BC,OAAO,EAAEnB,MAAO;MAChBoB,QAAQ,EAAEtB;IAAS,CACtB,CACH;EACL,IAEAA,QAAQ,iBAAIhB,KAAA,CAAAyB,aAAA,CAACrB,aAAa;IAACgC,IAAI,EAAE;EAAsC,CAAE,CAAC,eAC3EpC,KAAA,CAAAyB,aAAA,CAACvB,WAAW;IAACqC,GAAG,EAAEzB,WAAY;IAACP,GAAG,EAAEA,GAAI;IAACC,OAAO,EAAEA;EAAQ,GACrD,CAAC;IAAEgC;EAAO,CAAC,KAAKA,MAAM,CAAC,CACf,CACT,CAAC;AAEjB,CAAC","ignoreList":[]}
@@ -1 +0,0 @@
1
- export * from "./ImageEditor.js";
@@ -1,3 +0,0 @@
1
- export * from "./ImageEditor.js";
2
-
3
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./ImageEditor.js\";\n"],"mappings":"AAAA","ignoreList":[]}
@@ -1,4 +0,0 @@
1
- import type { ImageEditorTool } from "./types.js";
2
- import "cropperjs/dist/cropper.css";
3
- declare const tool: ImageEditorTool;
4
- export default tool;
@@ -1,67 +0,0 @@
1
- import React from "react";
2
- import { IconButton, Tooltip } from "@webiny/admin-ui";
3
- import { ReactComponent as CropIcon } from "@webiny/icons/crop.svg";
4
- import Cropper from "cropperjs";
5
- import "cropperjs/dist/cropper.css";
6
- let cropper = undefined;
7
- const renderForm = () => {
8
- return /*#__PURE__*/React.createElement("div", {
9
- style: {
10
- textAlign: "center"
11
- }
12
- }, "Click and drag to crop a portion of the image. Hold Shift to persist aspect ratio.");
13
- };
14
- const tool = {
15
- name: "crop",
16
- icon({
17
- activateTool
18
- }) {
19
- return /*#__PURE__*/React.createElement(Tooltip, {
20
- side: "bottom",
21
- content: "Crop",
22
- trigger: /*#__PURE__*/React.createElement(IconButton, {
23
- variant: "ghost",
24
- icon: /*#__PURE__*/React.createElement(CropIcon, null),
25
- onClick: () => activateTool("crop"),
26
- "data-testid": "crop-item"
27
- })
28
- });
29
- },
30
- renderForm,
31
- onActivate: ({
32
- canvas,
33
- options
34
- }) => {
35
- cropper = new Cropper(canvas.current, options);
36
- },
37
- cancel: () => cropper && cropper.destroy(),
38
- apply: ({
39
- canvas
40
- }) => {
41
- return new Promise(resolve => {
42
- if (!cropper) {
43
- resolve();
44
- return;
45
- }
46
- const current = canvas.current;
47
- const src = cropper.getCroppedCanvas().toDataURL();
48
- if (current) {
49
- const image = new window.Image();
50
- const ctx = current.getContext("2d");
51
- image.onload = () => {
52
- ctx.drawImage(image, 0, 0);
53
- current.width = image.width;
54
- current.height = image.height;
55
- ctx.drawImage(image, 0, 0);
56
- resolve();
57
- };
58
- image.src = src;
59
- }
60
- cropper.destroy();
61
- cropper = undefined;
62
- });
63
- }
64
- };
65
- export default tool;
66
-
67
- //# sourceMappingURL=crop.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","IconButton","Tooltip","ReactComponent","CropIcon","Cropper","cropper","undefined","renderForm","createElement","style","textAlign","tool","name","icon","activateTool","side","content","trigger","variant","onClick","onActivate","canvas","options","current","cancel","destroy","apply","Promise","resolve","src","getCroppedCanvas","toDataURL","image","window","Image","ctx","getContext","onload","drawImage","width","height"],"sources":["crop.tsx"],"sourcesContent":["import React from \"react\";\nimport type { ImageEditorTool } from \"./types.js\";\nimport { IconButton, Tooltip } from \"@webiny/admin-ui\";\nimport { ReactComponent as CropIcon } from \"@webiny/icons/crop.svg\";\nimport Cropper from \"cropperjs\";\nimport \"cropperjs/dist/cropper.css\";\n\nlet cropper: Cropper | undefined = undefined;\n\nconst renderForm = () => {\n return (\n <div style={{ textAlign: \"center\" }}>\n Click and drag to crop a portion of the image. Hold Shift to persist aspect ratio.\n </div>\n );\n};\n\nconst tool: ImageEditorTool = {\n name: \"crop\",\n icon({ activateTool }) {\n return (\n <Tooltip\n side={\"bottom\"}\n content={\"Crop\"}\n trigger={\n <IconButton\n variant={\"ghost\"}\n icon={<CropIcon />}\n onClick={() => activateTool(\"crop\")}\n data-testid={\"crop-item\"}\n />\n }\n />\n );\n },\n renderForm,\n onActivate: ({ canvas, options }) => {\n cropper = new Cropper(canvas.current as HTMLCanvasElement, options);\n },\n cancel: () => cropper && cropper.destroy(),\n apply: ({ canvas }) => {\n return new Promise((resolve: any) => {\n if (!cropper) {\n resolve();\n return;\n }\n\n const current = canvas.current;\n const src = cropper.getCroppedCanvas().toDataURL();\n if (current) {\n const image = new window.Image();\n const ctx = current.getContext(\"2d\") as CanvasRenderingContext2D;\n image.onload = () => {\n ctx.drawImage(image, 0, 0);\n current.width = image.width;\n current.height = image.height;\n\n ctx.drawImage(image, 0, 0);\n resolve();\n };\n image.src = src;\n }\n\n cropper.destroy();\n cropper = undefined;\n });\n }\n};\n\nexport default tool;\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AAEzB,SAASC,UAAU,EAAEC,OAAO,QAAQ,kBAAkB;AACtD,SAASC,cAAc,IAAIC,QAAQ,QAAQ,wBAAwB;AACnE,OAAOC,OAAO,MAAM,WAAW;AAC/B,OAAO,4BAA4B;AAEnC,IAAIC,OAA4B,GAAGC,SAAS;AAE5C,MAAMC,UAAU,GAAGA,CAAA,KAAM;EACrB,oBACIR,KAAA,CAAAS,aAAA;IAAKC,KAAK,EAAE;MAAEC,SAAS,EAAE;IAAS;EAAE,GAAC,oFAEhC,CAAC;AAEd,CAAC;AAED,MAAMC,IAAqB,GAAG;EAC1BC,IAAI,EAAE,MAAM;EACZC,IAAIA,CAAC;IAAEC;EAAa,CAAC,EAAE;IACnB,oBACIf,KAAA,CAAAS,aAAA,CAACP,OAAO;MACJc,IAAI,EAAE,QAAS;MACfC,OAAO,EAAE,MAAO;MAChBC,OAAO,eACHlB,KAAA,CAAAS,aAAA,CAACR,UAAU;QACPkB,OAAO,EAAE,OAAQ;QACjBL,IAAI,eAAEd,KAAA,CAAAS,aAAA,CAACL,QAAQ,MAAE,CAAE;QACnBgB,OAAO,EAAEA,CAAA,KAAML,YAAY,CAAC,MAAM,CAAE;QACpC,eAAa;MAAY,CAC5B;IACJ,CACJ,CAAC;EAEV,CAAC;EACDP,UAAU;EACVa,UAAU,EAAEA,CAAC;IAAEC,MAAM;IAAEC;EAAQ,CAAC,KAAK;IACjCjB,OAAO,GAAG,IAAID,OAAO,CAACiB,MAAM,CAACE,OAAO,EAAuBD,OAAO,CAAC;EACvE,CAAC;EACDE,MAAM,EAAEA,CAAA,KAAMnB,OAAO,IAAIA,OAAO,CAACoB,OAAO,CAAC,CAAC;EAC1CC,KAAK,EAAEA,CAAC;IAAEL;EAAO,CAAC,KAAK;IACnB,OAAO,IAAIM,OAAO,CAAEC,OAAY,IAAK;MACjC,IAAI,CAACvB,OAAO,EAAE;QACVuB,OAAO,CAAC,CAAC;QACT;MACJ;MAEA,MAAML,OAAO,GAAGF,MAAM,CAACE,OAAO;MAC9B,MAAMM,GAAG,GAAGxB,OAAO,CAACyB,gBAAgB,CAAC,CAAC,CAACC,SAAS,CAAC,CAAC;MAClD,IAAIR,OAAO,EAAE;QACT,MAAMS,KAAK,GAAG,IAAIC,MAAM,CAACC,KAAK,CAAC,CAAC;QAChC,MAAMC,GAAG,GAAGZ,OAAO,CAACa,UAAU,CAAC,IAAI,CAA6B;QAChEJ,KAAK,CAACK,MAAM,GAAG,MAAM;UACjBF,GAAG,CAACG,SAAS,CAACN,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;UAC1BT,OAAO,CAACgB,KAAK,GAAGP,KAAK,CAACO,KAAK;UAC3BhB,OAAO,CAACiB,MAAM,GAAGR,KAAK,CAACQ,MAAM;UAE7BL,GAAG,CAACG,SAAS,CAACN,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;UAC1BJ,OAAO,CAAC,CAAC;QACb,CAAC;QACDI,KAAK,CAACH,GAAG,GAAGA,GAAG;MACnB;MAEAxB,OAAO,CAACoB,OAAO,CAAC,CAAC;MACjBpB,OAAO,GAAGC,SAAS;IACvB,CAAC,CAAC;EACN;AACJ,CAAC;AAED,eAAeK,IAAI","ignoreList":[]}
@@ -1,3 +0,0 @@
1
- import type { ImageEditorTool } from "./types.js";
2
- declare const tool: ImageEditorTool;
3
- export default tool;
@@ -1,167 +0,0 @@
1
- /**
2
- * When using Caman, we added @ts-expect-error because it does not exist in packages, but it is loaded in packages/ui/src/ImageEditor/ImageEditor.tsx:38.
3
- * TODO: use some other library to edit images
4
- */
5
- import React from "react";
6
- import { ReactComponent as FilterIcon } from "@webiny/icons/tune.svg";
7
- import debounce from "lodash/debounce.js";
8
- import { Button, Grid, IconButton, Slider, Tooltip } from "@webiny/admin-ui";
9
- const sliders = [{
10
- key: "brightness",
11
- label: "Brightness",
12
- min: -100
13
- }, {
14
- key: "vibrance",
15
- label: "Vibrance",
16
- min: -100
17
- }, {
18
- key: "hue",
19
- label: "Hue",
20
- min: -100
21
- }, {
22
- key: "gamma",
23
- label: "Gamma"
24
- }, {
25
- key: "clip",
26
- label: "Clip"
27
- }, {
28
- key: "stackBlur",
29
- label: "Blur"
30
- }, {
31
- key: "contrast",
32
- label: "Contrast",
33
- min: -100
34
- }, {
35
- key: "saturation",
36
- label: "Saturation",
37
- min: -100
38
- }, {
39
- key: "exposure",
40
- label: "Exposure",
41
- min: -100
42
- }, {
43
- key: "sepia",
44
- label: "Sepia"
45
- }, {
46
- key: "noise",
47
- label: "Noise"
48
- }, {
49
- key: "sharpen",
50
- label: "Sharpen"
51
- }];
52
- class RenderForm extends React.Component {
53
- state = {
54
- processing: false,
55
- values: {}
56
- };
57
- componentDidMount() {
58
- this.resetFiltersValues();
59
- }
60
- applyFilters = debounce(() => {
61
- const {
62
- canvas
63
- } = this.props;
64
- const {
65
- values
66
- } = this.state;
67
- // eslint-disable-next-line @typescript-eslint/no-this-alias
68
- const component = this;
69
-
70
- // @ts-expect-error
71
- Caman(canvas.current, function () {
72
- // @ts-expect-error
73
- this.revert(false);
74
- Object.keys(values).forEach(
75
- // @ts-expect-error
76
- key => values[key] !== 0 && this[key] && this[key](values[key]));
77
- // @ts-expect-error
78
- this.render();
79
- component.setState({
80
- processing: false
81
- });
82
- });
83
- }, 200);
84
- resetFiltersValues = () => {
85
- this.setState(state => {
86
- sliders.reduce((output, current) => {
87
- state.values[current.key] = 0;
88
- return output;
89
- }, {});
90
- return state;
91
- });
92
- };
93
- render() {
94
- return /*#__PURE__*/React.createElement(Grid, null, /*#__PURE__*/React.createElement(React.Fragment, null, sliders.map(props => /*#__PURE__*/React.createElement(Grid.Column, {
95
- span: 4,
96
- key: props.key
97
- }, /*#__PURE__*/React.createElement(Slider, Object.assign({
98
- value: Number(this.state.values[props.key]),
99
- min: 0,
100
- max: 100,
101
- disabled: this.state.processing,
102
- onValueChange: value => {
103
- this.setState(state => {
104
- const values = {
105
- ...state.values
106
- };
107
- values[props.key] = value;
108
- return {
109
- ...state,
110
- processing: true,
111
- values
112
- };
113
- }, this.applyFilters);
114
- }
115
- }, props))))), /*#__PURE__*/React.createElement(Grid.Column, {
116
- span: 12,
117
- className: "text-center"
118
- }, /*#__PURE__*/React.createElement(Button, {
119
- text: "Reset filters",
120
- variant: "secondary",
121
- onClick: () => {
122
- this.setState({
123
- processing: true
124
- }, () => {
125
- this.resetFiltersValues();
126
- this.applyFilters();
127
- this.setState({
128
- processing: false
129
- });
130
- });
131
- }
132
- })));
133
- }
134
- }
135
- const tool = {
136
- name: "filter",
137
- icon({
138
- activateTool
139
- }) {
140
- return /*#__PURE__*/React.createElement(Tooltip, {
141
- trigger: /*#__PURE__*/React.createElement(IconButton, {
142
- variant: "ghost",
143
- icon: /*#__PURE__*/React.createElement(FilterIcon, null),
144
- onClick: () => activateTool("filter"),
145
- "data-testid": "filter-item"
146
- }),
147
- content: "Filter"
148
- });
149
- },
150
- renderForm(props) {
151
- return /*#__PURE__*/React.createElement(RenderForm, props);
152
- },
153
- cancel: ({
154
- canvas
155
- }) => {
156
- // @ts-expect-error
157
- Caman(canvas.current, function () {
158
- // @ts-expect-error
159
- this.revert(false);
160
- // @ts-expect-error
161
- this.render();
162
- });
163
- }
164
- };
165
- export default tool;
166
-
167
- //# sourceMappingURL=filter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","ReactComponent","FilterIcon","debounce","Button","Grid","IconButton","Slider","Tooltip","sliders","key","label","min","RenderForm","Component","state","processing","values","componentDidMount","resetFiltersValues","applyFilters","canvas","props","component","Caman","current","revert","Object","keys","forEach","render","setState","reduce","output","createElement","Fragment","map","Column","span","assign","value","Number","max","disabled","onValueChange","className","text","variant","onClick","tool","name","icon","activateTool","trigger","content","renderForm","cancel"],"sources":["filter.tsx"],"sourcesContent":["/**\n * When using Caman, we added @ts-expect-error because it does not exist in packages, but it is loaded in packages/ui/src/ImageEditor/ImageEditor.tsx:38.\n * TODO: use some other library to edit images\n */\nimport React from \"react\";\nimport { ReactComponent as FilterIcon } from \"@webiny/icons/tune.svg\";\nimport debounce from \"lodash/debounce.js\";\nimport { Button, Grid, IconButton, Slider, Tooltip } from \"@webiny/admin-ui\";\nimport type { ImageEditorTool } from \"./types.js\";\n\ninterface RenderFormState {\n values: Record<string, any>;\n processing: boolean;\n}\n\ninterface RenderFormProps {\n canvas: any;\n renderApplyCancel?: () => void;\n}\n\nconst sliders = [\n {\n key: \"brightness\",\n label: \"Brightness\",\n min: -100\n },\n {\n key: \"vibrance\",\n label: \"Vibrance\",\n min: -100\n },\n {\n key: \"hue\",\n label: \"Hue\",\n min: -100\n },\n {\n key: \"gamma\",\n label: \"Gamma\"\n },\n {\n key: \"clip\",\n label: \"Clip\"\n },\n {\n key: \"stackBlur\",\n label: \"Blur\"\n },\n {\n key: \"contrast\",\n label: \"Contrast\",\n min: -100\n },\n {\n key: \"saturation\",\n label: \"Saturation\",\n min: -100\n },\n {\n key: \"exposure\",\n label: \"Exposure\",\n min: -100\n },\n {\n key: \"sepia\",\n label: \"Sepia\"\n },\n {\n key: \"noise\",\n label: \"Noise\"\n },\n {\n key: \"sharpen\",\n label: \"Sharpen\"\n }\n];\n\nclass RenderForm extends React.Component<RenderFormProps, RenderFormState> {\n public override state: RenderFormState = {\n processing: false,\n values: {}\n };\n\n public override componentDidMount() {\n this.resetFiltersValues();\n }\n\n private readonly applyFilters = debounce(() => {\n const { canvas } = this.props;\n const { values } = this.state;\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const component = this;\n\n // @ts-expect-error\n Caman(canvas.current, function () {\n // @ts-expect-error\n this.revert(false);\n Object.keys(values).forEach(\n // @ts-expect-error\n key => values[key] !== 0 && this[key] && this[key](values[key])\n );\n // @ts-expect-error\n this.render();\n component.setState({ processing: false });\n });\n }, 200);\n\n private readonly resetFiltersValues = () => {\n this.setState(state => {\n sliders.reduce((output, current) => {\n state.values[current.key] = 0;\n return output;\n }, {});\n\n return state;\n });\n };\n\n public override render() {\n return (\n <Grid>\n <>\n {sliders.map(props => (\n <Grid.Column span={4} key={props.key}>\n <Slider\n value={Number(this.state.values[props.key])}\n min={0}\n max={100}\n disabled={this.state.processing}\n onValueChange={(value: number) => {\n this.setState(state => {\n const values = { ...state.values };\n values[props.key] = value;\n\n return { ...state, processing: true, values };\n }, this.applyFilters);\n }}\n {...props}\n />\n </Grid.Column>\n ))}\n </>\n <Grid.Column span={12} className={\"text-center\"}>\n <Button\n text={\"Reset filters\"}\n variant={\"secondary\"}\n onClick={() => {\n this.setState({ processing: true }, () => {\n this.resetFiltersValues();\n this.applyFilters();\n this.setState({ processing: false });\n });\n }}\n />\n </Grid.Column>\n </Grid>\n );\n }\n}\n\nconst tool: ImageEditorTool = {\n name: \"filter\",\n icon({ activateTool }) {\n return (\n <Tooltip\n trigger={\n <IconButton\n variant={\"ghost\"}\n icon={<FilterIcon />}\n onClick={() => activateTool(\"filter\")}\n data-testid={\"filter-item\"}\n />\n }\n content={\"Filter\"}\n />\n );\n },\n renderForm(props) {\n return <RenderForm {...props} />;\n },\n cancel: ({ canvas }) => {\n // @ts-expect-error\n Caman(canvas.current, function () {\n // @ts-expect-error\n this.revert(false);\n // @ts-expect-error\n this.render();\n });\n }\n};\n\nexport default tool;\n"],"mappings":"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","ignoreList":[]}
@@ -1,4 +0,0 @@
1
- import "cropperjs/dist/cropper.css";
2
- import type { ImageEditorTool } from "./types.js";
3
- declare const tool: ImageEditorTool;
4
- export default tool;
@@ -1,94 +0,0 @@
1
- import React from "react";
2
- import { Button, IconButton, Tooltip } from "@webiny/admin-ui";
3
- import { ReactComponent as FlipIcon } from "@webiny/icons/flip.svg";
4
- import Cropper from "cropperjs";
5
- import "cropperjs/dist/cropper.css";
6
- let cropper;
7
- const flipped = {
8
- x: 1,
9
- y: 1
10
- };
11
- const renderForm = () => {
12
- return /*#__PURE__*/React.createElement("div", {
13
- className: "flex justify-center gap-sm"
14
- }, /*#__PURE__*/React.createElement(Button, {
15
- text: "FlipX",
16
- variant: "secondary",
17
- onClick: () => {
18
- if (!cropper) {
19
- return;
20
- }
21
- flipped.x = flipped.x === 1 ? -1 : 1;
22
- cropper.scaleX(flipped.x);
23
- }
24
- }), /*#__PURE__*/React.createElement(Button, {
25
- text: "FlipY",
26
- variant: "secondary",
27
- onClick: () => {
28
- if (!cropper) {
29
- return;
30
- }
31
- flipped.y = flipped.y === 1 ? -1 : 1;
32
- cropper.scaleY(flipped.y);
33
- }
34
- }));
35
- };
36
- const tool = {
37
- name: "flip",
38
- icon({
39
- activateTool
40
- }) {
41
- return /*#__PURE__*/React.createElement(Tooltip, {
42
- side: "bottom",
43
- content: "Flip",
44
- trigger: /*#__PURE__*/React.createElement(IconButton, {
45
- variant: "ghost",
46
- icon: /*#__PURE__*/React.createElement(FlipIcon, null),
47
- onClick: () => activateTool("flip"),
48
- "data-testid": "flip-item"
49
- })
50
- });
51
- },
52
- renderForm,
53
- cancel: () => cropper && cropper.destroy(),
54
- onActivate: ({
55
- canvas
56
- }) => {
57
- cropper = new Cropper(canvas.current, {
58
- background: false,
59
- modal: false,
60
- guides: false,
61
- dragMode: "none",
62
- highlight: false,
63
- autoCrop: false
64
- });
65
- },
66
- apply: ({
67
- canvas
68
- }) => {
69
- return new Promise(resolve => {
70
- if (!cropper) {
71
- resolve();
72
- return;
73
- }
74
- const current = canvas.current;
75
- const src = cropper.getCroppedCanvas().toDataURL();
76
- if (current) {
77
- const image = new window.Image();
78
- const ctx = current.getContext("2d");
79
- image.onload = () => {
80
- ctx.drawImage(image, 0, 0);
81
- current.width = image.width;
82
- current.height = image.height;
83
- ctx.drawImage(image, 0, 0);
84
- resolve();
85
- };
86
- image.src = src;
87
- }
88
- cropper.destroy();
89
- });
90
- }
91
- };
92
- export default tool;
93
-
94
- //# sourceMappingURL=flip.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","Button","IconButton","Tooltip","ReactComponent","FlipIcon","Cropper","cropper","flipped","x","y","renderForm","createElement","className","text","variant","onClick","scaleX","scaleY","tool","name","icon","activateTool","side","content","trigger","cancel","destroy","onActivate","canvas","current","background","modal","guides","dragMode","highlight","autoCrop","apply","Promise","resolve","src","getCroppedCanvas","toDataURL","image","window","Image","ctx","getContext","onload","drawImage","width","height"],"sources":["flip.tsx"],"sourcesContent":["import React from \"react\";\nimport { Button, IconButton, Tooltip } from \"@webiny/admin-ui\";\nimport { ReactComponent as FlipIcon } from \"@webiny/icons/flip.svg\";\nimport Cropper from \"cropperjs\";\nimport \"cropperjs/dist/cropper.css\";\nimport type { ImageEditorTool } from \"./types.js\";\n\nlet cropper: Cropper;\n\nconst flipped = { x: 1, y: 1 };\n\nconst renderForm = () => {\n return (\n <div className={\"flex justify-center gap-sm\"}>\n <Button\n text={\"FlipX\"}\n variant={\"secondary\"}\n onClick={() => {\n if (!cropper) {\n return;\n }\n\n flipped.x = flipped.x === 1 ? -1 : 1;\n cropper.scaleX(flipped.x);\n }}\n />\n <Button\n text={\"FlipY\"}\n variant={\"secondary\"}\n onClick={() => {\n if (!cropper) {\n return;\n }\n\n flipped.y = flipped.y === 1 ? -1 : 1;\n cropper.scaleY(flipped.y);\n }}\n />\n </div>\n );\n};\n\nconst tool: ImageEditorTool = {\n name: \"flip\",\n icon({ activateTool }) {\n return (\n <Tooltip\n side={\"bottom\"}\n content={\"Flip\"}\n trigger={\n <IconButton\n variant={\"ghost\"}\n icon={<FlipIcon />}\n onClick={() => activateTool(\"flip\")}\n data-testid={\"flip-item\"}\n />\n }\n />\n );\n },\n renderForm,\n cancel: () => cropper && cropper.destroy(),\n onActivate: ({ canvas }) => {\n cropper = new Cropper(canvas.current as HTMLCanvasElement, {\n background: false,\n modal: false,\n guides: false,\n dragMode: \"none\",\n highlight: false,\n autoCrop: false\n });\n },\n apply: ({ canvas }) => {\n return new Promise((resolve: any) => {\n if (!cropper) {\n resolve();\n return;\n }\n\n const current = canvas.current;\n const src = cropper.getCroppedCanvas().toDataURL();\n if (current) {\n const image = new window.Image();\n const ctx = current.getContext(\"2d\") as CanvasRenderingContext2D;\n image.onload = () => {\n ctx.drawImage(image, 0, 0);\n current.width = image.width;\n current.height = image.height;\n\n ctx.drawImage(image, 0, 0);\n resolve();\n };\n image.src = src;\n }\n\n cropper.destroy();\n });\n }\n};\n\nexport default tool;\n"],"mappings":"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","ignoreList":[]}
@@ -1,4 +0,0 @@
1
- export { default as crop } from "./crop.js";
2
- export { default as flip } from "./flip.js";
3
- export { default as filter } from "./filter.js";
4
- export { default as rotate } from "./rotate.js";
@@ -1,6 +0,0 @@
1
- export { default as crop } from "./crop.js";
2
- export { default as flip } from "./flip.js";
3
- export { default as filter } from "./filter.js";
4
- export { default as rotate } from "./rotate.js";
5
-
6
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["default","crop","flip","filter","rotate"],"sources":["index.ts"],"sourcesContent":["export { default as crop } from \"./crop.js\";\nexport { default as flip } from \"./flip.js\";\nexport { default as filter } from \"./filter.js\";\nexport { default as rotate } from \"./rotate.js\";\n"],"mappings":"AAAA,SAASA,OAAO,IAAIC,IAAI;AACxB,SAASD,OAAO,IAAIE,IAAI;AACxB,SAASF,OAAO,IAAIG,MAAM;AAC1B,SAASH,OAAO,IAAII,MAAM","ignoreList":[]}
@@ -1,4 +0,0 @@
1
- import type { ImageEditorTool } from "./types.js";
2
- import "cropperjs/dist/cropper.css";
3
- declare const tool: ImageEditorTool;
4
- export default tool;
@@ -1,93 +0,0 @@
1
- import React from "react";
2
- import { IconButton, Slider, Tooltip } from "@webiny/admin-ui";
3
- import { ReactComponent as RotateRight } from "@webiny/icons/rotate_right.svg";
4
- import Cropper from "cropperjs";
5
- import "cropperjs/dist/cropper.css";
6
- let cropper;
7
- class RenderForm extends React.Component {
8
- state = {
9
- rangeInput: 0
10
- };
11
- render() {
12
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Slider, {
13
- label: "Range Input",
14
- value: Number(this.state.rangeInput),
15
- min: 0,
16
- max: 360,
17
- step: 10,
18
- onValueChange: value => {
19
- this.setState({
20
- rangeInput: value
21
- }, async () => {
22
- if (cropper) {
23
- cropper.rotateTo(parseInt(String(value), 10));
24
- }
25
- });
26
- }
27
- }));
28
- }
29
- }
30
- const tool = {
31
- name: "rotate",
32
- icon({
33
- activateTool
34
- }) {
35
- return /*#__PURE__*/React.createElement(Tooltip, {
36
- side: "bottom",
37
- content: "Rotate",
38
- trigger: /*#__PURE__*/React.createElement(IconButton, {
39
- variant: "ghost",
40
- icon: /*#__PURE__*/React.createElement(RotateRight, null),
41
- onClick: () => activateTool("rotate"),
42
- "data-testid": "rotate-item"
43
- })
44
- });
45
- },
46
- renderForm(props) {
47
- return /*#__PURE__*/React.createElement(RenderForm, props);
48
- },
49
- onActivate: ({
50
- canvas
51
- }) => {
52
- /**
53
- * We can safely cast canvas.current as HTMLCanvasElement
54
- */
55
- cropper = new Cropper(canvas.current, {
56
- background: false,
57
- modal: false,
58
- guides: false,
59
- dragMode: "none",
60
- highlight: false,
61
- autoCrop: false
62
- });
63
- },
64
- cancel: () => cropper && cropper.destroy(),
65
- apply: ({
66
- canvas
67
- }) => {
68
- return new Promise(resolve => {
69
- if (!cropper) {
70
- resolve();
71
- return;
72
- }
73
- const current = canvas.current;
74
- const src = cropper.getCroppedCanvas().toDataURL();
75
- if (current) {
76
- const image = new window.Image();
77
- const ctx = current.getContext("2d");
78
- image.onload = () => {
79
- ctx.drawImage(image, 0, 0);
80
- current.width = image.width;
81
- current.height = image.height;
82
- ctx.drawImage(image, 0, 0);
83
- };
84
- image.src = src;
85
- resolve();
86
- }
87
- cropper.destroy();
88
- });
89
- }
90
- };
91
- export default tool;
92
-
93
- //# sourceMappingURL=rotate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","IconButton","Slider","Tooltip","ReactComponent","RotateRight","Cropper","cropper","RenderForm","Component","state","rangeInput","render","createElement","label","value","Number","min","max","step","onValueChange","setState","rotateTo","parseInt","String","tool","name","icon","activateTool","side","content","trigger","variant","onClick","renderForm","props","onActivate","canvas","current","background","modal","guides","dragMode","highlight","autoCrop","cancel","destroy","apply","Promise","resolve","src","getCroppedCanvas","toDataURL","image","window","Image","ctx","getContext","onload","drawImage","width","height"],"sources":["rotate.tsx"],"sourcesContent":["import React from \"react\";\nimport { IconButton, Slider, Tooltip } from \"@webiny/admin-ui\";\nimport { ReactComponent as RotateRight } from \"@webiny/icons/rotate_right.svg\";\nimport type { ImageEditorTool } from \"./types.js\";\n\nimport Cropper from \"cropperjs\";\nimport \"cropperjs/dist/cropper.css\";\n\nlet cropper: Cropper;\n\nclass RenderForm extends React.Component<any, any> {\n public override state = {\n rangeInput: 0\n };\n\n public override render() {\n return (\n <div>\n <Slider\n label={\"Range Input\"}\n value={Number(this.state.rangeInput)}\n min={0}\n max={360}\n step={10}\n onValueChange={(value: number) => {\n this.setState({ rangeInput: value }, async () => {\n if (cropper) {\n cropper.rotateTo(parseInt(String(value), 10));\n }\n });\n }}\n />\n </div>\n );\n }\n}\n\nconst tool: ImageEditorTool = {\n name: \"rotate\",\n icon({ activateTool }) {\n return (\n <Tooltip\n side={\"bottom\"}\n content={\"Rotate\"}\n trigger={\n <IconButton\n variant={\"ghost\"}\n icon={<RotateRight />}\n onClick={() => activateTool(\"rotate\")}\n data-testid={\"rotate-item\"}\n />\n }\n />\n );\n },\n renderForm(props) {\n return <RenderForm {...props} />;\n },\n onActivate: ({ canvas }) => {\n /**\n * We can safely cast canvas.current as HTMLCanvasElement\n */\n cropper = new Cropper(canvas.current as HTMLCanvasElement, {\n background: false,\n modal: false,\n guides: false,\n dragMode: \"none\",\n highlight: false,\n autoCrop: false\n });\n },\n cancel: () => cropper && cropper.destroy(),\n apply: ({ canvas }) => {\n return new Promise((resolve: any) => {\n if (!cropper) {\n resolve();\n return;\n }\n\n const current = canvas.current;\n const src = cropper.getCroppedCanvas().toDataURL();\n if (current) {\n const image = new window.Image();\n const ctx = current.getContext(\"2d\") as CanvasRenderingContext2D;\n image.onload = () => {\n ctx.drawImage(image, 0, 0);\n current.width = image.width;\n current.height = image.height;\n\n ctx.drawImage(image, 0, 0);\n };\n image.src = src;\n resolve();\n }\n\n cropper.destroy();\n });\n }\n};\n\nexport default tool;\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,UAAU,EAAEC,MAAM,EAAEC,OAAO,QAAQ,kBAAkB;AAC9D,SAASC,cAAc,IAAIC,WAAW,QAAQ,gCAAgC;AAG9E,OAAOC,OAAO,MAAM,WAAW;AAC/B,OAAO,4BAA4B;AAEnC,IAAIC,OAAgB;AAEpB,MAAMC,UAAU,SAASR,KAAK,CAACS,SAAS,CAAW;EAC/BC,KAAK,GAAG;IACpBC,UAAU,EAAE;EAChB,CAAC;EAEeC,MAAMA,CAAA,EAAG;IACrB,oBACIZ,KAAA,CAAAa,aAAA,2BACIb,KAAA,CAAAa,aAAA,CAACX,MAAM;MACHY,KAAK,EAAE,aAAc;MACrBC,KAAK,EAAEC,MAAM,CAAC,IAAI,CAACN,KAAK,CAACC,UAAU,CAAE;MACrCM,GAAG,EAAE,CAAE;MACPC,GAAG,EAAE,GAAI;MACTC,IAAI,EAAE,EAAG;MACTC,aAAa,EAAGL,KAAa,IAAK;QAC9B,IAAI,CAACM,QAAQ,CAAC;UAAEV,UAAU,EAAEI;QAAM,CAAC,EAAE,YAAY;UAC7C,IAAIR,OAAO,EAAE;YACTA,OAAO,CAACe,QAAQ,CAACC,QAAQ,CAACC,MAAM,CAACT,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;UACjD;QACJ,CAAC,CAAC;MACN;IAAE,CACL,CACA,CAAC;EAEd;AACJ;AAEA,MAAMU,IAAqB,GAAG;EAC1BC,IAAI,EAAE,QAAQ;EACdC,IAAIA,CAAC;IAAEC;EAAa,CAAC,EAAE;IACnB,oBACI5B,KAAA,CAAAa,aAAA,CAACV,OAAO;MACJ0B,IAAI,EAAE,QAAS;MACfC,OAAO,EAAE,QAAS;MAClBC,OAAO,eACH/B,KAAA,CAAAa,aAAA,CAACZ,UAAU;QACP+B,OAAO,EAAE,OAAQ;QACjBL,IAAI,eAAE3B,KAAA,CAAAa,aAAA,CAACR,WAAW,MAAE,CAAE;QACtB4B,OAAO,EAAEA,CAAA,KAAML,YAAY,CAAC,QAAQ,CAAE;QACtC,eAAa;MAAc,CAC9B;IACJ,CACJ,CAAC;EAEV,CAAC;EACDM,UAAUA,CAACC,KAAK,EAAE;IACd,oBAAOnC,KAAA,CAAAa,aAAA,CAACL,UAAU,EAAK2B,KAAQ,CAAC;EACpC,CAAC;EACDC,UAAU,EAAEA,CAAC;IAAEC;EAAO,CAAC,KAAK;IACxB;AACR;AACA;IACQ9B,OAAO,GAAG,IAAID,OAAO,CAAC+B,MAAM,CAACC,OAAO,EAAuB;MACvDC,UAAU,EAAE,KAAK;MACjBC,KAAK,EAAE,KAAK;MACZC,MAAM,EAAE,KAAK;MACbC,QAAQ,EAAE,MAAM;MAChBC,SAAS,EAAE,KAAK;MAChBC,QAAQ,EAAE;IACd,CAAC,CAAC;EACN,CAAC;EACDC,MAAM,EAAEA,CAAA,KAAMtC,OAAO,IAAIA,OAAO,CAACuC,OAAO,CAAC,CAAC;EAC1CC,KAAK,EAAEA,CAAC;IAAEV;EAAO,CAAC,KAAK;IACnB,OAAO,IAAIW,OAAO,CAAEC,OAAY,IAAK;MACjC,IAAI,CAAC1C,OAAO,EAAE;QACV0C,OAAO,CAAC,CAAC;QACT;MACJ;MAEA,MAAMX,OAAO,GAAGD,MAAM,CAACC,OAAO;MAC9B,MAAMY,GAAG,GAAG3C,OAAO,CAAC4C,gBAAgB,CAAC,CAAC,CAACC,SAAS,CAAC,CAAC;MAClD,IAAId,OAAO,EAAE;QACT,MAAMe,KAAK,GAAG,IAAIC,MAAM,CAACC,KAAK,CAAC,CAAC;QAChC,MAAMC,GAAG,GAAGlB,OAAO,CAACmB,UAAU,CAAC,IAAI,CAA6B;QAChEJ,KAAK,CAACK,MAAM,GAAG,MAAM;UACjBF,GAAG,CAACG,SAAS,CAACN,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;UAC1Bf,OAAO,CAACsB,KAAK,GAAGP,KAAK,CAACO,KAAK;UAC3BtB,OAAO,CAACuB,MAAM,GAAGR,KAAK,CAACQ,MAAM;UAE7BL,GAAG,CAACG,SAAS,CAACN,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9B,CAAC;QACDA,KAAK,CAACH,GAAG,GAAGA,GAAG;QACfD,OAAO,CAAC,CAAC;MACb;MAEA1C,OAAO,CAACuC,OAAO,CAAC,CAAC;IACrB,CAAC,CAAC;EACN;AACJ,CAAC;AAED,eAAerB,IAAI","ignoreList":[]}
@@ -1,32 +0,0 @@
1
- import type React from "react";
2
- export type ToolbarTool = "crop" | "flip" | "rotate" | "filter";
3
- interface RenderFormParams {
4
- canvas: React.RefObject<HTMLCanvasElement | null>;
5
- image: HTMLImageElement;
6
- renderApplyCancel?: () => void;
7
- options?: {
8
- [key: string]: any;
9
- };
10
- }
11
- interface OnActivateParams {
12
- options: any;
13
- canvas: React.RefObject<HTMLCanvasElement | null>;
14
- }
15
- interface IconParams {
16
- activateTool: (tool: ToolbarTool) => void;
17
- }
18
- interface ApplyParams {
19
- canvas: React.RefObject<HTMLCanvasElement | null>;
20
- }
21
- interface CancelParams {
22
- canvas: React.RefObject<HTMLCanvasElement | null>;
23
- }
24
- export interface ImageEditorTool {
25
- name: string;
26
- apply?: (params: ApplyParams) => void;
27
- cancel?: (params: CancelParams) => void;
28
- onActivate?: (params: OnActivateParams) => void;
29
- icon: (params: IconParams) => React.ReactElement<any>;
30
- renderForm?: (params: RenderFormParams) => React.ReactNode;
31
- }
32
- export {};
@@ -1,3 +0,0 @@
1
- export {};
2
-
3
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type React from \"react\";\n\nexport type ToolbarTool = \"crop\" | \"flip\" | \"rotate\" | \"filter\";\n\ninterface RenderFormParams {\n canvas: React.RefObject<HTMLCanvasElement | null>;\n image: HTMLImageElement;\n renderApplyCancel?: () => void;\n options?: { [key: string]: any };\n}\n\ninterface OnActivateParams {\n options: any;\n canvas: React.RefObject<HTMLCanvasElement | null>;\n}\n\ninterface IconParams {\n activateTool: (tool: ToolbarTool) => void;\n}\n\ninterface ApplyParams {\n canvas: React.RefObject<HTMLCanvasElement | null>;\n}\n\ninterface CancelParams {\n canvas: React.RefObject<HTMLCanvasElement | null>;\n}\n\nexport interface ImageEditorTool {\n name: string;\n apply?: (params: ApplyParams) => void;\n cancel?: (params: CancelParams) => void;\n onActivate?: (params: OnActivateParams) => void;\n icon: (params: IconParams) => React.ReactElement<any>;\n renderForm?: (params: RenderFormParams) => React.ReactNode;\n}\n"],"mappings":"","ignoreList":[]}
@@ -1,2 +0,0 @@
1
- import React from "react";
2
- export declare const EditImage: () => React.JSX.Element | null;
@@ -1,106 +0,0 @@
1
- import React from "react";
2
- // @ts-expect-error
3
- import dataURLtoBlob from "dataurl-to-blob";
4
- import { ImageEditorDialog } from "../../../../components/ImageEditor/ImageEditorDialog.js";
5
- import { ReactComponent as EditIcon } from "@webiny/icons/edit.svg";
6
- import { FileManagerViewConfig, useFile, useFileDetails, useFileManagerApi, useFileManagerView } from "../../../../index.js";
7
- import { useSnackbar } from "@webiny/app-admin";
8
- function toDataUrl(url) {
9
- return new Promise(resolve => {
10
- const xhr = new window.XMLHttpRequest();
11
- xhr.onload = function () {
12
- const reader = new window.FileReader();
13
- reader.onloadend = function () {
14
- resolve(reader.result);
15
- };
16
- reader.readAsDataURL(xhr.response);
17
- };
18
- xhr.open("GET", url);
19
- xhr.responseType = "blob";
20
- xhr.send();
21
- });
22
- }
23
- const initialState = {
24
- showImageEditor: false,
25
- dataUrl: null
26
- };
27
- const reducer = (state, action) => {
28
- const next = {
29
- ...state
30
- };
31
- switch (action.type) {
32
- case "setDataUrl":
33
- next.dataUrl = action.dataUrl;
34
- next.showImageEditor = true;
35
- break;
36
- case "hideImageEditor":
37
- next.dataUrl = null;
38
- next.showImageEditor = false;
39
- break;
40
- }
41
- return next;
42
- };
43
- const {
44
- FileDetails
45
- } = FileManagerViewConfig;
46
- export const EditImage = () => {
47
- const {
48
- file
49
- } = useFile();
50
- const {
51
- canEdit
52
- } = useFileManagerApi();
53
- const fileDetails = useFileDetails();
54
- const {
55
- uploadFile
56
- } = useFileManagerView();
57
- const [state, dispatch] = React.useReducer(reducer, initialState);
58
- const {
59
- showSnackbar
60
- } = useSnackbar();
61
- if (!file.type.startsWith("image/")) {
62
- return null;
63
- }
64
-
65
- // Render nothing if the user doesn't have the required permissions for "edit".
66
- if (!canEdit(file)) {
67
- return null;
68
- }
69
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(FileDetails.Action.Button, {
70
- className: "order-last ml-auto",
71
- label: "Edit image",
72
- "data-testid": "fm-edit-image-button",
73
- icon: /*#__PURE__*/React.createElement(EditIcon, null),
74
- onAction: async () => {
75
- const dataUrl = await toDataUrl(file.src);
76
- dispatch({
77
- type: "setDataUrl",
78
- dataUrl
79
- });
80
- }
81
- }), /*#__PURE__*/React.createElement(ImageEditorDialog, {
82
- "data-testid": "fm-image-editor-dialog",
83
- dialogZIndex: 100,
84
- open: state.showImageEditor,
85
- src: state.dataUrl,
86
- onClose: () => dispatch({
87
- type: "hideImageEditor"
88
- }),
89
- onAccept: async src => {
90
- const blob = dataURLtoBlob(src);
91
- blob.name = file.name;
92
- blob.key = file.key.split("/").pop();
93
- const newFile = await uploadFile(blob);
94
- if (newFile) {
95
- showSnackbar("A new version of the image has been created!");
96
- dispatch({
97
- type: "hideImageEditor"
98
- });
99
- fileDetails.setFile(newFile);
100
- fileDetails.close();
101
- }
102
- }
103
- }));
104
- };
105
-
106
- //# sourceMappingURL=EditImage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","dataURLtoBlob","ImageEditorDialog","ReactComponent","EditIcon","FileManagerViewConfig","useFile","useFileDetails","useFileManagerApi","useFileManagerView","useSnackbar","toDataUrl","url","Promise","resolve","xhr","window","XMLHttpRequest","onload","reader","FileReader","onloadend","result","readAsDataURL","response","open","responseType","send","initialState","showImageEditor","dataUrl","reducer","state","action","next","type","FileDetails","EditImage","file","canEdit","fileDetails","uploadFile","dispatch","useReducer","showSnackbar","startsWith","createElement","Fragment","Action","Button","className","label","icon","onAction","src","dialogZIndex","onClose","onAccept","blob","name","key","split","pop","newFile","setFile","close"],"sources":["EditImage.tsx"],"sourcesContent":["import React from \"react\";\n// @ts-expect-error\nimport dataURLtoBlob from \"dataurl-to-blob\";\nimport { ImageEditorDialog } from \"~/components/ImageEditor/ImageEditorDialog.js\";\nimport { ReactComponent as EditIcon } from \"@webiny/icons/edit.svg\";\nimport {\n FileManagerViewConfig,\n useFile,\n useFileDetails,\n useFileManagerApi,\n useFileManagerView\n} from \"~/index.js\";\nimport { useSnackbar } from \"@webiny/app-admin\";\n\nfunction toDataUrl(url: string): Promise<string> {\n return new Promise((resolve: (value: string) => void) => {\n const xhr = new window.XMLHttpRequest();\n xhr.onload = function () {\n const reader = new window.FileReader();\n reader.onloadend = function () {\n resolve(reader.result as string);\n };\n reader.readAsDataURL(xhr.response);\n };\n xhr.open(\"GET\", url);\n xhr.responseType = \"blob\";\n xhr.send();\n });\n}\n\ninterface State {\n showImageEditor: boolean;\n dataUrl: string | null;\n}\n\ninterface Action {\n type: \"setDataUrl\" | \"hideImageEditor\";\n dataUrl?: string | null;\n}\n\nconst initialState: State = {\n showImageEditor: false,\n dataUrl: null\n};\n\nconst reducer = (state: State, action: Action): State => {\n const next: State = { ...state };\n\n switch (action.type) {\n case \"setDataUrl\":\n next.dataUrl = action.dataUrl as string;\n next.showImageEditor = true;\n break;\n case \"hideImageEditor\":\n next.dataUrl = null;\n next.showImageEditor = false;\n break;\n }\n\n return next;\n};\n\nconst { FileDetails } = FileManagerViewConfig;\n\nexport const EditImage = () => {\n const { file } = useFile();\n const { canEdit } = useFileManagerApi();\n const fileDetails = useFileDetails();\n const { uploadFile } = useFileManagerView();\n const [state, dispatch] = React.useReducer(reducer, initialState);\n const { showSnackbar } = useSnackbar();\n\n if (!file.type.startsWith(\"image/\")) {\n return null;\n }\n\n // Render nothing if the user doesn't have the required permissions for \"edit\".\n if (!canEdit(file)) {\n return null;\n }\n\n return (\n <>\n <FileDetails.Action.Button\n className={\"order-last ml-auto\"}\n label={\"Edit image\"}\n data-testid={\"fm-edit-image-button\"}\n icon={<EditIcon />}\n onAction={async () => {\n const dataUrl = await toDataUrl(file.src);\n dispatch({ type: \"setDataUrl\", dataUrl });\n }}\n />\n <ImageEditorDialog\n data-testid={\"fm-image-editor-dialog\"}\n dialogZIndex={100}\n open={state.showImageEditor}\n src={state.dataUrl as string}\n onClose={() => dispatch({ type: \"hideImageEditor\" })}\n onAccept={async src => {\n const blob = dataURLtoBlob(src);\n blob.name = file.name;\n blob.key = file.key.split(\"/\").pop();\n const newFile = await uploadFile(blob);\n\n if (newFile) {\n showSnackbar(\"A new version of the image has been created!\");\n dispatch({ type: \"hideImageEditor\" });\n fileDetails.setFile(newFile);\n fileDetails.close();\n }\n }}\n />\n </>\n );\n};\n"],"mappings":"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","ignoreList":[]}