@elementor/editor-variables 0.10.0 → 0.12.0

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.
package/dist/index.mjs CHANGED
@@ -26,9 +26,190 @@ import { Box, Divider, ListItemIcon, ListItemText, MenuList } from "@elementor/u
26
26
  // src/hooks/use-prop-variables.ts
27
27
  import { useMemo } from "react";
28
28
 
29
+ // src/api.ts
30
+ import { httpService } from "@elementor/http-client";
31
+ var BASE_PATH = "elementor/v1/variables";
32
+ var apiClient = {
33
+ list: () => {
34
+ return httpService().get(BASE_PATH + "/list");
35
+ },
36
+ create: (type, label, value) => {
37
+ return httpService().post(BASE_PATH + "/create", {
38
+ type,
39
+ label,
40
+ value
41
+ });
42
+ },
43
+ update: (id, label, value) => {
44
+ return httpService().put(BASE_PATH + "/update", {
45
+ id,
46
+ label,
47
+ value
48
+ });
49
+ },
50
+ delete: (id) => {
51
+ return httpService().post(BASE_PATH + "/delete", { id });
52
+ },
53
+ restore: (id) => {
54
+ return httpService().post(BASE_PATH + "/restore", { id });
55
+ }
56
+ };
57
+
58
+ // src/storage.ts
59
+ var STORAGE_KEY = "elementor-global-variables";
60
+ var STORAGE_WATERMARK_KEY = "elementor-global-variables-watermark";
61
+ var OP_RW = "RW";
62
+ var OP_RO = "RO";
63
+ var Storage = class {
64
+ state;
65
+ constructor() {
66
+ this.state = {
67
+ watermark: -1,
68
+ variables: {}
69
+ };
70
+ }
71
+ load() {
72
+ this.state.watermark = parseInt(localStorage.getItem(STORAGE_WATERMARK_KEY) || "-1");
73
+ this.state.variables = JSON.parse(localStorage.getItem(STORAGE_KEY) || "{}");
74
+ return this.state.variables;
75
+ }
76
+ fill(variables, watermark) {
77
+ this.state.watermark = watermark;
78
+ this.state.variables = variables;
79
+ localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
80
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
81
+ }
82
+ add(id, variable) {
83
+ this.load();
84
+ this.state.variables[id] = variable;
85
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
86
+ }
87
+ update(id, variable) {
88
+ this.load();
89
+ this.state.variables[id] = variable;
90
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
91
+ }
92
+ watermark(watermark) {
93
+ this.state.watermark = watermark;
94
+ localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
95
+ }
96
+ watermarkDiff(operation, newWatermark) {
97
+ const diff = newWatermark - this.state.watermark;
98
+ if (OP_RW === operation) {
99
+ return 1 !== diff;
100
+ }
101
+ if (OP_RO === operation) {
102
+ return 0 !== diff;
103
+ }
104
+ return false;
105
+ }
106
+ };
107
+
108
+ // src/service.ts
109
+ var storage = new Storage();
110
+ var service = {
111
+ variables: () => {
112
+ return storage.load();
113
+ },
114
+ init: () => {
115
+ service.load();
116
+ },
117
+ load: () => {
118
+ return apiClient.list().then((response) => {
119
+ const { success, data: payload } = response.data;
120
+ if (!success) {
121
+ throw new Error("Unexpected response from server");
122
+ }
123
+ return payload;
124
+ }).then((data) => {
125
+ const { variables, watermark } = data;
126
+ storage.fill(variables, watermark);
127
+ return variables;
128
+ });
129
+ },
130
+ create: ({ type, label, value }) => {
131
+ return apiClient.create(type, label, value).then((response) => {
132
+ const { success, data: payload } = response.data;
133
+ if (!success) {
134
+ throw new Error("Unexpected response from server");
135
+ }
136
+ return payload;
137
+ }).then((data) => {
138
+ const { variable, watermark } = data;
139
+ handleWatermark(OP_RW, watermark);
140
+ const { id: variableId, ...createdVariable } = variable;
141
+ storage.add(variableId, createdVariable);
142
+ return {
143
+ id: variableId,
144
+ variable: createdVariable
145
+ };
146
+ });
147
+ },
148
+ update: (id, { label, value }) => {
149
+ return apiClient.update(id, label, value).then((response) => {
150
+ const { success, data: payload } = response.data;
151
+ if (!success) {
152
+ throw new Error("Unexpected response from server");
153
+ }
154
+ return payload;
155
+ }).then((data) => {
156
+ const { variable, watermark } = data;
157
+ handleWatermark(OP_RW, watermark);
158
+ const { id: variableId, ...updatedVariable } = variable;
159
+ storage.update(variableId, updatedVariable);
160
+ return {
161
+ id: variableId,
162
+ variable: updatedVariable
163
+ };
164
+ });
165
+ },
166
+ delete: (id) => {
167
+ return apiClient.delete(id).then((response) => {
168
+ const { success, data: payload } = response.data;
169
+ if (!success) {
170
+ throw new Error("Unexpected response from server");
171
+ }
172
+ return payload;
173
+ }).then((data) => {
174
+ const { variable, watermark } = data;
175
+ handleWatermark(OP_RW, watermark);
176
+ const { id: variableId, ...deletedVariable } = variable;
177
+ storage.update(variableId, deletedVariable);
178
+ return {
179
+ id: variableId,
180
+ variable: deletedVariable
181
+ };
182
+ });
183
+ },
184
+ restore: (id) => {
185
+ return apiClient.restore(id).then((response) => {
186
+ const { success, data: payload } = response.data;
187
+ if (!success) {
188
+ throw new Error("Unexpected response from server");
189
+ }
190
+ return payload;
191
+ }).then((data) => {
192
+ const { variable, watermark } = data;
193
+ handleWatermark(OP_RW, watermark);
194
+ const { id: variableId, ...restoredVariable } = variable;
195
+ storage.update(variableId, restoredVariable);
196
+ return {
197
+ id: variableId,
198
+ variable: restoredVariable
199
+ };
200
+ });
201
+ }
202
+ };
203
+ var handleWatermark = (operation, newWatermark) => {
204
+ if (storage.watermarkDiff(operation, newWatermark)) {
205
+ setTimeout(() => service.load(), 500);
206
+ }
207
+ storage.watermark(newWatermark);
208
+ };
209
+
29
210
  // src/create-style-variables-repository.ts
30
211
  var createStyleVariablesRepository = () => {
31
- const variables2 = {};
212
+ const variables = {};
32
213
  let subscription;
33
214
  const subscribe = (cb) => {
34
215
  subscription = cb;
@@ -39,17 +220,17 @@ var createStyleVariablesRepository = () => {
39
220
  };
40
221
  const notify = () => {
41
222
  if (typeof subscription === "function") {
42
- subscription({ ...variables2 });
223
+ subscription({ ...variables });
43
224
  }
44
225
  };
45
226
  const shouldUpdate = (key, newValue) => {
46
- return !(key in variables2) || variables2[key] !== newValue;
227
+ return !(key in variables) || variables[key] !== newValue;
47
228
  };
48
229
  const applyUpdates = (updatedVars) => {
49
230
  let hasChanges = false;
50
231
  for (const [key, { value }] of Object.entries(updatedVars)) {
51
232
  if (shouldUpdate(key, value)) {
52
- variables2[key] = value;
233
+ variables[key] = value;
53
234
  hasChanges = true;
54
235
  }
55
236
  }
@@ -74,6 +255,7 @@ var usePropVariables = (propKey) => {
74
255
  return useMemo(() => normalizeVariables(propKey), [propKey]);
75
256
  };
76
257
  var useVariable = (key) => {
258
+ const variables = service.variables();
77
259
  if (!variables?.[key]) {
78
260
  return null;
79
261
  }
@@ -83,24 +265,21 @@ var useVariable = (key) => {
83
265
  };
84
266
  };
85
267
  var normalizeVariables = (propKey) => {
268
+ const variables = service.variables();
269
+ styleVariablesRepository.update(variables);
86
270
  return Object.entries(variables).filter(([, { type }]) => type === propKey).map(([key, { label, value }]) => ({
87
271
  key,
88
272
  label,
89
273
  value
90
274
  }));
91
275
  };
92
- var createVariable = (variable) => {
93
- const id = generateId();
94
- variables[id] = variable;
95
- styleVariablesRepository.update({
96
- [id]: variable
276
+ var createVariable = (newVariable) => {
277
+ return service.create(newVariable).then(({ id, variable }) => {
278
+ styleVariablesRepository.update({
279
+ [id]: variable
280
+ });
281
+ return id;
97
282
  });
98
- return id;
99
- };
100
- var variables = window?.ElementorV4Variables || {};
101
- var generateId = (prefix = "e-gv") => {
102
- const randomHex = Math.random().toString(16).slice(2, 9);
103
- return `${prefix}${randomHex}`;
104
283
  };
105
284
 
106
285
  // src/prop-types/color-variable-prop-type.ts
@@ -122,12 +301,12 @@ var StyledMenuItem = styled2(MenuItem)(() => ({
122
301
  // src/components/color-variables-selection.tsx
123
302
  var ColorVariablesSelection = ({ onSelect }) => {
124
303
  const { value: variable, setValue: setVariable } = useBoundProp(colorVariablePropTypeUtil);
125
- const variables2 = usePropVariables(colorVariablePropTypeUtil.key);
304
+ const variables = usePropVariables(colorVariablePropTypeUtil.key);
126
305
  const handleSetColorVariable = (key) => {
127
306
  setVariable(key);
128
307
  onSelect?.();
129
308
  };
130
- return /* @__PURE__ */ React.createElement(Fragment, null, /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement(Box, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React.createElement(MenuList, { role: "listbox", tabIndex: 0 }, variables2.map(({ value, label, key }) => /* @__PURE__ */ React.createElement(
309
+ return /* @__PURE__ */ React.createElement(Fragment, null, /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement(Box, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React.createElement(MenuList, { role: "listbox", tabIndex: 0 }, variables.map(({ value, label, key }) => /* @__PURE__ */ React.createElement(
131
310
  StyledMenuItem,
132
311
  {
133
312
  key,
@@ -167,16 +346,16 @@ var ColorVariablesSelection = ({ onSelect }) => {
167
346
  // src/components/variables-selection-popover.tsx
168
347
  import * as React3 from "react";
169
348
  import { useId, useRef as useRef2 } from "react";
349
+ import { PopoverHeader as PopoverHeader2 } from "@elementor/editor-ui";
170
350
  import { ColorFilterIcon, DetachIcon, PlusIcon } from "@elementor/icons";
171
351
  import {
172
352
  bindPopover as bindPopover2,
173
353
  bindTrigger,
174
354
  Box as Box3,
175
- CloseButton as CloseButton2,
176
355
  IconButton,
177
356
  Popover as Popover2,
178
357
  Stack as Stack2,
179
- Typography as Typography2,
358
+ Typography,
180
359
  UnstableTag as Tag,
181
360
  usePopupState
182
361
  } from "@elementor/ui";
@@ -186,23 +365,23 @@ import { __ as __2 } from "@wordpress/i18n";
186
365
  import * as React2 from "react";
187
366
  import { useRef, useState } from "react";
188
367
  import { useBoundProp as useBoundProp2 } from "@elementor/editor-controls";
368
+ import { PopoverHeader } from "@elementor/editor-ui";
189
369
  import { BrushIcon } from "@elementor/icons";
190
370
  import {
191
371
  bindPopover,
192
372
  Box as Box2,
193
373
  Button,
194
374
  CardActions,
195
- CloseButton,
196
375
  Divider as Divider2,
197
376
  FormLabel,
198
377
  Grid,
199
378
  Popover,
200
379
  Stack,
201
380
  TextField,
202
- Typography,
203
381
  UnstableColorField
204
382
  } from "@elementor/ui";
205
383
  import { __ } from "@wordpress/i18n";
384
+ var SIZE = "tiny";
206
385
  var ColorVariableCreation = ({ popupState }) => {
207
386
  const { setValue: setVariable } = useBoundProp2(colorVariablePropTypeUtil);
208
387
  const [color, setColor] = useState("");
@@ -217,13 +396,14 @@ var ColorVariableCreation = ({ popupState }) => {
217
396
  popupState.close();
218
397
  };
219
398
  const handleCreate = () => {
220
- const key = createVariable({
399
+ createVariable({
221
400
  value: color,
222
401
  label,
223
402
  type: colorVariablePropTypeUtil.key
403
+ }).then((key) => {
404
+ setVariable(key);
405
+ closePopover();
224
406
  });
225
- setVariable(key);
226
- closePopover();
227
407
  };
228
408
  const isInValidForm = () => {
229
409
  return !color?.trim() || !label?.trim();
@@ -236,14 +416,14 @@ var ColorVariableCreation = ({ popupState }) => {
236
416
  anchorOrigin: { vertical: "bottom", horizontal: "right" },
237
417
  transformOrigin: { vertical: "top", horizontal: "right" }
238
418
  },
239
- /* @__PURE__ */ React2.createElement(Stack, { direction: "row", alignItems: "center", pl: 1.5, pr: 0.5, py: 1.5 }, /* @__PURE__ */ React2.createElement(BrushIcon, { fontSize: "tiny", sx: { mr: 0.5 } }), /* @__PURE__ */ React2.createElement(Typography, { variant: "subtitle2" }, __("Create variable", "elementor")), /* @__PURE__ */ React2.createElement(
240
- CloseButton,
419
+ /* @__PURE__ */ React2.createElement(
420
+ PopoverHeader,
241
421
  {
242
- slotProps: { icon: { fontSize: "small" } },
243
- sx: { ml: "auto" },
244
- onClick: closePopover
422
+ title: __("Create variable", "elementor"),
423
+ onClose: closePopover,
424
+ icon: /* @__PURE__ */ React2.createElement(BrushIcon, { fontSize: SIZE })
245
425
  }
246
- )),
426
+ ),
247
427
  /* @__PURE__ */ React2.createElement(Divider2, null),
248
428
  /* @__PURE__ */ React2.createElement(Stack, { p: 1.5, gap: 1.5 }, /* @__PURE__ */ React2.createElement(Grid, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React2.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React2.createElement(FormLabel, { size: "small" }, __("Name", "elementor"))), /* @__PURE__ */ React2.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React2.createElement(
249
429
  TextField,
@@ -274,6 +454,7 @@ var ColorVariableCreation = ({ popupState }) => {
274
454
  };
275
455
 
276
456
  // src/components/variables-selection-popover.tsx
457
+ var SIZE2 = "tiny";
277
458
  var VariablesSelectionPopover = ({
278
459
  selectedVariable,
279
460
  unlinkVariable,
@@ -290,6 +471,7 @@ var VariablesSelectionPopover = ({
290
471
  };
291
472
  const anchorRef = useRef2(null);
292
473
  const { label } = selectedVariable;
474
+ const colorCreationEnabled = colorVariablePropTypeUtil.key === selectedVariable.type;
293
475
  return /* @__PURE__ */ React3.createElement(Box3, { ref: anchorRef }, /* @__PURE__ */ React3.createElement(
294
476
  Tag,
295
477
  {
@@ -297,8 +479,8 @@ var VariablesSelectionPopover = ({
297
479
  showActionsOnHover: true,
298
480
  ...bindTrigger(popupState),
299
481
  startIcon: /* @__PURE__ */ React3.createElement(Stack2, { spacing: 1, direction: "row", alignItems: "center" }, startTagAdornment, /* @__PURE__ */ React3.createElement(ColorFilterIcon, { fontSize: "inherit", sx: { mr: 1 } })),
300
- label: /* @__PURE__ */ React3.createElement(Box3, { sx: { display: "inline-grid" } }, /* @__PURE__ */ React3.createElement(Typography2, { sx: { textOverflow: "ellipsis", overflowX: "hidden" }, variant: "subtitle2" }, label)),
301
- actions: /* @__PURE__ */ React3.createElement(IconButton, { size: "tiny", onClick: unlinkVariable, "aria-label": __2("Unlink", "elementor") }, /* @__PURE__ */ React3.createElement(DetachIcon, { fontSize: "tiny" }))
482
+ label: /* @__PURE__ */ React3.createElement(Box3, { sx: { display: "inline-grid" } }, /* @__PURE__ */ React3.createElement(Typography, { sx: { textOverflow: "ellipsis", overflowX: "hidden" }, variant: "subtitle2" }, label)),
483
+ actions: /* @__PURE__ */ React3.createElement(IconButton, { size: SIZE2, onClick: unlinkVariable, "aria-label": __2("Unlink", "elementor") }, /* @__PURE__ */ React3.createElement(DetachIcon, { fontSize: SIZE2 }))
302
484
  }
303
485
  ), /* @__PURE__ */ React3.createElement(
304
486
  Popover2,
@@ -309,17 +491,28 @@ var VariablesSelectionPopover = ({
309
491
  anchorOrigin: { vertical: "bottom", horizontal: "right" },
310
492
  transformOrigin: { vertical: "top", horizontal: "right" }
311
493
  },
312
- /* @__PURE__ */ React3.createElement(Stack2, { direction: "row", alignItems: "center", pl: 1.5, pr: 0.5, py: 1.5 }, /* @__PURE__ */ React3.createElement(ColorFilterIcon, { fontSize: "tiny", sx: { mr: 0.5 } }), /* @__PURE__ */ React3.createElement(Typography2, { variant: "subtitle2" }, __2("Variables", "elementor")), /* @__PURE__ */ React3.createElement(Stack2, { direction: "row", sx: { ml: "auto" } }, /* @__PURE__ */ React3.createElement(
313
- IconButton,
494
+ /* @__PURE__ */ React3.createElement(
495
+ PopoverHeader2,
314
496
  {
315
- ...bindTrigger(creationPopupState),
316
- size: "tiny",
317
- onClick: handleCreateButtonClick
318
- },
319
- /* @__PURE__ */ React3.createElement(PlusIcon, { fontSize: "tiny" })
320
- ), /* @__PURE__ */ React3.createElement(CloseButton2, { slotProps: { icon: { fontSize: "tiny" } }, onClick: closePopover }))),
497
+ title: __2("Variables", "elementor"),
498
+ onClose: closePopover,
499
+ icon: /* @__PURE__ */ React3.createElement(ColorFilterIcon, { fontSize: SIZE2 }),
500
+ actions: [
501
+ /* @__PURE__ */ React3.createElement(
502
+ IconButton,
503
+ {
504
+ key: "createVariable",
505
+ ...bindTrigger(creationPopupState),
506
+ size: SIZE2,
507
+ onClick: handleCreateButtonClick
508
+ },
509
+ /* @__PURE__ */ React3.createElement(PlusIcon, { fontSize: SIZE2 })
510
+ )
511
+ ]
512
+ }
513
+ ),
321
514
  children?.({ closePopover })
322
- ), /* @__PURE__ */ React3.createElement(ColorVariableCreation, { popupState: creationPopupState }));
515
+ ), colorCreationEnabled && /* @__PURE__ */ React3.createElement(ColorVariableCreation, { popupState: creationPopupState }));
323
516
  };
324
517
 
325
518
  // src/controls/color-variables-selection-control.tsx
@@ -421,12 +614,12 @@ import { EditIcon as EditIcon2, TextIcon } from "@elementor/icons";
421
614
  import { Box as Box4, Divider as Divider3, ListItemIcon as ListItemIcon2, ListItemText as ListItemText2, MenuList as MenuList2 } from "@elementor/ui";
422
615
  var FontVariablesSelection = ({ onSelect }) => {
423
616
  const { value: variable, setValue: setVariable } = useBoundProp5(fontVariablePropTypeUtil);
424
- const variables2 = usePropVariables(fontVariablePropTypeUtil.key);
617
+ const variables = usePropVariables(fontVariablePropTypeUtil.key);
425
618
  const handleSetVariable = (key) => {
426
619
  setVariable(key);
427
620
  onSelect?.();
428
621
  };
429
- return /* @__PURE__ */ React6.createElement(Fragment2, null, /* @__PURE__ */ React6.createElement(Divider3, null), /* @__PURE__ */ React6.createElement(Box4, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React6.createElement(MenuList2, { role: "listbox", tabIndex: 0 }, variables2.map(({ value, label, key }) => /* @__PURE__ */ React6.createElement(
622
+ return /* @__PURE__ */ React6.createElement(Fragment2, null, /* @__PURE__ */ React6.createElement(Divider3, null), /* @__PURE__ */ React6.createElement(Box4, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React6.createElement(MenuList2, { role: "listbox", tabIndex: 0 }, variables.map(({ value, label, key }) => /* @__PURE__ */ React6.createElement(
430
623
  StyledMenuItem,
431
624
  {
432
625
  key,
@@ -536,200 +729,19 @@ function usePortalContainer() {
536
729
  return useListenTo(commandEndEvent("editor/documents/attach-preview"), () => getCanvasIframeDocument()?.head);
537
730
  }
538
731
  function useStyleVariables() {
539
- const [variables2, setVariables] = useState2({});
732
+ const [variables, setVariables] = useState2({});
540
733
  useEffect(() => {
541
734
  const unsubscribe = styleVariablesRepository.subscribe(setVariables);
542
735
  return () => {
543
736
  unsubscribe();
544
737
  };
545
738
  }, []);
546
- return variables2;
739
+ return variables;
547
740
  }
548
- function convertToCssVariables(variables2) {
549
- return Object.entries(variables2).map(([key, value]) => `--${key}:${value};`).join("");
741
+ function convertToCssVariables(variables) {
742
+ return Object.entries(variables).map(([key, value]) => `--${key}:${value};`).join("");
550
743
  }
551
744
 
552
- // src/api.ts
553
- import { httpService } from "@elementor/http-client";
554
- var BASE_PATH = "elementor/v1/variables";
555
- var apiClient = {
556
- list: () => {
557
- return httpService().get(BASE_PATH + "/list");
558
- },
559
- create: (type, label, value) => {
560
- return httpService().post(BASE_PATH + "/create", {
561
- type,
562
- label,
563
- value
564
- });
565
- },
566
- update: (id, label, value) => {
567
- return httpService().put(BASE_PATH + "/update", {
568
- id,
569
- label,
570
- value
571
- });
572
- },
573
- delete: (id) => {
574
- return httpService().post(BASE_PATH + "/delete", { id });
575
- },
576
- restore: (id) => {
577
- return httpService().post(BASE_PATH + "/restore", { id });
578
- }
579
- };
580
-
581
- // src/storage.ts
582
- var STORAGE_KEY = "elementor-global-variables";
583
- var STORAGE_WATERMARK_KEY = "elementor-global-variables-watermark";
584
- var OP_RW = "RW";
585
- var OP_RO = "RO";
586
- var Storage = class {
587
- state;
588
- constructor() {
589
- this.state = {
590
- watermark: -1,
591
- variables: {}
592
- };
593
- }
594
- load() {
595
- this.state.watermark = parseInt(localStorage.getItem(STORAGE_WATERMARK_KEY) || "-1");
596
- this.state.variables = JSON.parse(localStorage.getItem(STORAGE_KEY) || "{}");
597
- return this.state.variables;
598
- }
599
- fill(variables2, watermark) {
600
- this.state.watermark = watermark;
601
- this.state.variables = variables2;
602
- localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
603
- localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
604
- }
605
- add(id, variable) {
606
- this.load();
607
- this.state.variables[id] = variable;
608
- localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
609
- }
610
- update(id, variable) {
611
- this.load();
612
- this.state.variables[id] = variable;
613
- localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
614
- }
615
- watermark(watermark) {
616
- this.state.watermark = watermark;
617
- localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
618
- }
619
- watermarkDiff(operation, newWatermark) {
620
- const diff = newWatermark - this.state.watermark;
621
- if (OP_RW === operation) {
622
- return 1 !== diff;
623
- }
624
- if (OP_RO === operation) {
625
- return 0 !== diff;
626
- }
627
- return false;
628
- }
629
- };
630
-
631
- // src/service.ts
632
- var storage = new Storage();
633
- var service = {
634
- variables: () => {
635
- return storage.load();
636
- },
637
- init: () => {
638
- service.load();
639
- },
640
- load: () => {
641
- return apiClient.list().then((response) => {
642
- const { success, data: payload } = response.data;
643
- if (!success) {
644
- throw new Error("Unexpected response from server");
645
- }
646
- return payload;
647
- }).then((data) => {
648
- const { variables: variables2, watermark } = data;
649
- storage.fill(variables2, watermark);
650
- return variables2;
651
- });
652
- },
653
- create: ({ type, label, value }) => {
654
- return apiClient.create(type, label, value).then((response) => {
655
- const { success, data: payload } = response.data;
656
- if (!success) {
657
- throw new Error("Unexpected response from server");
658
- }
659
- return payload;
660
- }).then((data) => {
661
- const { variable, watermark } = data;
662
- handleWatermark(OP_RW, watermark);
663
- const { id: variableId, ...createdVariable } = variable;
664
- storage.add(variableId, createdVariable);
665
- return {
666
- id: variableId,
667
- variable: createdVariable
668
- };
669
- });
670
- },
671
- update: (id, { label, value }) => {
672
- return apiClient.update(id, label, value).then((response) => {
673
- const { success, data: payload } = response.data;
674
- if (!success) {
675
- throw new Error("Unexpected response from server");
676
- }
677
- return payload;
678
- }).then((data) => {
679
- const { variable, watermark } = data;
680
- handleWatermark(OP_RW, watermark);
681
- const { id: variableId, ...updatedVariable } = variable;
682
- storage.update(variableId, updatedVariable);
683
- return {
684
- id: variableId,
685
- variable: updatedVariable
686
- };
687
- });
688
- },
689
- delete: (id) => {
690
- return apiClient.delete(id).then((response) => {
691
- const { success, data: payload } = response.data;
692
- if (!success) {
693
- throw new Error("Unexpected response from server");
694
- }
695
- return payload;
696
- }).then((data) => {
697
- const { variable, watermark } = data;
698
- handleWatermark(OP_RW, watermark);
699
- const { id: variableId, ...deletedVariable } = variable;
700
- storage.update(variableId, deletedVariable);
701
- return {
702
- id: variableId,
703
- variable: deletedVariable
704
- };
705
- });
706
- },
707
- restore: (id) => {
708
- return apiClient.restore(id).then((response) => {
709
- const { success, data: payload } = response.data;
710
- if (!success) {
711
- throw new Error("Unexpected response from server");
712
- }
713
- return payload;
714
- }).then((data) => {
715
- const { variable, watermark } = data;
716
- handleWatermark(OP_RW, watermark);
717
- const { id: variableId, ...restoredVariable } = variable;
718
- storage.update(variableId, restoredVariable);
719
- return {
720
- id: variableId,
721
- variable: restoredVariable
722
- };
723
- });
724
- }
725
- };
726
- var handleWatermark = (operation, newWatermark) => {
727
- if (storage.watermarkDiff(operation, newWatermark)) {
728
- setTimeout(() => service.load(), 500);
729
- }
730
- storage.watermark(newWatermark);
731
- };
732
-
733
745
  // src/init.ts
734
746
  function init() {
735
747
  initColorVariables();