qa-notes 1.0.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.
@@ -0,0 +1,2136 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var K = require('react');
5
+
6
+ class NotesKitError extends Error {
7
+ constructor(message, status, body) {
8
+ super(message);
9
+ this.name = "NotesKitError";
10
+ this.status = status;
11
+ this.body = body;
12
+ }
13
+ }
14
+
15
+ class NotesApi {
16
+ constructor(config) {
17
+ this.config = config;
18
+ }
19
+ /* ── helpers ── */
20
+ async resolveToken() {
21
+ const { getToken } = this.config;
22
+ if (!getToken) return null;
23
+ if (typeof getToken === "string") return getToken;
24
+ return getToken();
25
+ }
26
+ async request(path, init = {}) {
27
+ var _a, _b, _c;
28
+ const token = await this.resolveToken();
29
+ const url = `${this.config.apiBaseUrl.replace(/\/+$/, "")}${path}`;
30
+ const headers = {
31
+ "Content-Type": "application/json",
32
+ ...this.config.headers
33
+ };
34
+ if (token) {
35
+ headers["Authorization"] = `Bearer ${token}`;
36
+ }
37
+ const res = await fetch(url, {
38
+ ...init,
39
+ headers: { ...headers, ...init.headers },
40
+ credentials: token ? "same-origin" : "include"
41
+ });
42
+ if (!res.ok) {
43
+ const body = await res.json().catch(() => null);
44
+ const err = new NotesKitError(
45
+ (_a = body == null ? void 0 : body.message) != null ? _a : `Request failed: ${res.status}`,
46
+ res.status,
47
+ body
48
+ );
49
+ (_c = (_b = this.config).onError) == null ? void 0 : _c.call(_b, err);
50
+ throw err;
51
+ }
52
+ if (res.status === 204) return void 0;
53
+ return res.json();
54
+ }
55
+ /* ── Notes ── */
56
+ async listNotes(params) {
57
+ const qs = new URLSearchParams();
58
+ if (params == null ? void 0 : params.search) qs.set("search", params.search);
59
+ if (params == null ? void 0 : params.folderId) qs.set("folderId", params.folderId);
60
+ if ((params == null ? void 0 : params.rootOnly) != null) qs.set("rootOnly", String(params.rootOnly));
61
+ if (params == null ? void 0 : params.from) qs.set("from", params.from);
62
+ if (params == null ? void 0 : params.to) qs.set("to", params.to);
63
+ if ((params == null ? void 0 : params.page) != null) qs.set("page", String(params.page));
64
+ if ((params == null ? void 0 : params.size) != null) qs.set("size", String(params.size));
65
+ if (params == null ? void 0 : params.sort) qs.set("sort", params.sort);
66
+ const query = qs.toString();
67
+ return this.request(`/notes${query ? `?${query}` : ""}`);
68
+ }
69
+ async suggest(prefix, limit = 5) {
70
+ const qs = new URLSearchParams({ prefix, limit: String(limit) });
71
+ return this.request(`/notes/suggest?${qs}`);
72
+ }
73
+ async getNote(id) {
74
+ return this.request(`/notes/${id}`);
75
+ }
76
+ async createNote(payload) {
77
+ return this.request("/notes", {
78
+ method: "POST",
79
+ body: JSON.stringify(payload)
80
+ });
81
+ }
82
+ async updateNote(id, payload) {
83
+ return this.request(`/notes/${id}`, {
84
+ method: "PUT",
85
+ body: JSON.stringify(payload)
86
+ });
87
+ }
88
+ async moveNote(id, payload) {
89
+ return this.request(`/notes/${id}/move`, {
90
+ method: "PUT",
91
+ body: JSON.stringify(payload)
92
+ });
93
+ }
94
+ async cloneNote(id, payload) {
95
+ return this.request(`/notes/${id}/clone`, {
96
+ method: "POST",
97
+ body: JSON.stringify(payload)
98
+ });
99
+ }
100
+ async deleteNote(id) {
101
+ return this.request(`/notes/${id}`, { method: "DELETE" });
102
+ }
103
+ /* ── Folders ── */
104
+ async listFolders() {
105
+ return this.request("/folders");
106
+ }
107
+ async getFolderTree() {
108
+ return this.request("/folders/tree");
109
+ }
110
+ async getFolder(id) {
111
+ return this.request(`/folders/${id}`);
112
+ }
113
+ async getFolderChildren(id) {
114
+ return this.request(`/folders/${id}/children`);
115
+ }
116
+ async createFolder(payload) {
117
+ return this.request("/folders", {
118
+ method: "POST",
119
+ body: JSON.stringify(payload)
120
+ });
121
+ }
122
+ async updateFolder(id, payload) {
123
+ return this.request(`/folders/${id}`, {
124
+ method: "PUT",
125
+ body: JSON.stringify(payload)
126
+ });
127
+ }
128
+ async deleteFolder(id) {
129
+ return this.request(`/folders/${id}`, { method: "DELETE" });
130
+ }
131
+ }
132
+
133
+ const NotesKitContext = K.createContext(null);
134
+ function useNotesKitContext() {
135
+ const ctx = K.useContext(NotesKitContext);
136
+ if (!ctx) {
137
+ throw new Error(
138
+ "[@nurtelecom-qa/qa-notes] useNotesKitContext must be used inside <NotesKitProvider>"
139
+ );
140
+ }
141
+ return ctx;
142
+ }
143
+ function NotesKitProvider({
144
+ config,
145
+ durationFetch,
146
+ children
147
+ }) {
148
+ var _a;
149
+ const resolvedTheme = (_a = config.theme) != null ? _a : "dark";
150
+ const value = K.useMemo(
151
+ () => ({
152
+ api: new NotesApi(config),
153
+ config,
154
+ theme: resolvedTheme,
155
+ durationFetch
156
+ }),
157
+ // eslint-disable-next-line react-hooks/exhaustive-deps
158
+ [config.apiBaseUrl, config.getToken, resolvedTheme, durationFetch]
159
+ );
160
+ return /* @__PURE__ */ jsxRuntime.jsx(NotesKitContext.Provider, { value, children });
161
+ }
162
+
163
+ function useNotes(initial) {
164
+ var _a;
165
+ const { api } = useNotesKitContext();
166
+ const [notes, setNotes] = K.useState([]);
167
+ const [totalElements, setTotalElements] = K.useState(0);
168
+ const [totalPages, setTotalPages] = K.useState(0);
169
+ const [loading, setLoading] = K.useState(false);
170
+ const [error, setError] = K.useState(null);
171
+ const [params, setParamsState] = K.useState(initial != null ? initial : {});
172
+ const paramsRef = K.useRef(params);
173
+ paramsRef.current = params;
174
+ const currentPage = (_a = params.page) != null ? _a : 0;
175
+ const fetchNotes = K.useCallback(
176
+ async (override) => {
177
+ const merged = { ...paramsRef.current, ...override };
178
+ if (override) setParamsState(merged);
179
+ setLoading(true);
180
+ setError(null);
181
+ try {
182
+ const res = await api.listNotes(merged);
183
+ setNotes(res.content);
184
+ setTotalElements(res.page.totalElements);
185
+ setTotalPages(res.page.totalPages);
186
+ } catch (e) {
187
+ setError(e instanceof Error ? e : new Error(String(e)));
188
+ } finally {
189
+ setLoading(false);
190
+ }
191
+ },
192
+ [api]
193
+ );
194
+ const create = K.useCallback(
195
+ async (payload) => {
196
+ const note = await api.createNote(payload);
197
+ setNotes((prev) => [note, ...prev]);
198
+ setTotalElements((t) => t + 1);
199
+ return note;
200
+ },
201
+ [api]
202
+ );
203
+ const update = K.useCallback(
204
+ async (id, payload) => {
205
+ const updated = await api.updateNote(id, payload);
206
+ setNotes((prev) => prev.map((n) => n.id === id ? updated : n));
207
+ return updated;
208
+ },
209
+ [api]
210
+ );
211
+ const move = K.useCallback(
212
+ async (id, payload) => {
213
+ const moved = await api.moveNote(id, payload);
214
+ setNotes((prev) => prev.map((n) => n.id === id ? moved : n));
215
+ return moved;
216
+ },
217
+ [api]
218
+ );
219
+ const clone = K.useCallback(
220
+ async (id, payload) => {
221
+ const cloned = await api.cloneNote(id, payload);
222
+ return cloned;
223
+ },
224
+ [api]
225
+ );
226
+ const remove = K.useCallback(
227
+ async (id) => {
228
+ await api.deleteNote(id);
229
+ setNotes((prev) => prev.filter((n) => n.id !== id));
230
+ setTotalElements((t) => t - 1);
231
+ },
232
+ [api]
233
+ );
234
+ const setParams = K.useCallback((p) => {
235
+ setParamsState((prev) => ({ ...prev, ...p }));
236
+ }, []);
237
+ const goToPage = K.useCallback((page) => {
238
+ setParamsState((prev) => ({ ...prev, page }));
239
+ }, []);
240
+ K.useEffect(() => {
241
+ fetchNotes();
242
+ }, [params.search, params.folderId, params.rootOnly, params.from, params.to, params.page, params.size, params.sort]);
243
+ const { durationFetch } = useNotesKitContext();
244
+ K.useEffect(() => {
245
+ if (!durationFetch) return;
246
+ const id = setInterval(() => {
247
+ api.listNotes(paramsRef.current).then((res) => {
248
+ setNotes(res.content);
249
+ setTotalElements(res.page.totalElements);
250
+ setTotalPages(res.page.totalPages);
251
+ }).catch(() => {
252
+ });
253
+ }, durationFetch);
254
+ return () => clearInterval(id);
255
+ }, [api, durationFetch]);
256
+ return { notes, totalElements, totalPages, currentPage, loading, error, params, fetch: fetchNotes, create, update, move, clone, remove, setParams, goToPage };
257
+ }
258
+
259
+ function useFolders() {
260
+ const { api } = useNotesKitContext();
261
+ const [folders, setFolders] = K.useState([]);
262
+ const [tree, setTree] = K.useState([]);
263
+ const [loading, setLoading] = K.useState(false);
264
+ const [error, setError] = K.useState(null);
265
+ const fetchFolders = K.useCallback(async () => {
266
+ setLoading(true);
267
+ setError(null);
268
+ try {
269
+ const res = await api.listFolders();
270
+ setFolders(res);
271
+ } catch (e) {
272
+ setError(e instanceof Error ? e : new Error(String(e)));
273
+ } finally {
274
+ setLoading(false);
275
+ }
276
+ }, [api]);
277
+ const fetchTree = K.useCallback(async () => {
278
+ setLoading(true);
279
+ setError(null);
280
+ try {
281
+ const res = await api.getFolderTree();
282
+ setTree(res);
283
+ } catch (e) {
284
+ setError(e instanceof Error ? e : new Error(String(e)));
285
+ } finally {
286
+ setLoading(false);
287
+ }
288
+ }, [api]);
289
+ const getFolder = K.useCallback(
290
+ async (id) => api.getFolder(id),
291
+ [api]
292
+ );
293
+ const getChildren = K.useCallback(
294
+ async (id) => api.getFolderChildren(id),
295
+ [api]
296
+ );
297
+ const create = K.useCallback(
298
+ async (payload) => {
299
+ const folder = await api.createFolder(payload);
300
+ setFolders((prev) => [...prev, folder]);
301
+ return folder;
302
+ },
303
+ [api]
304
+ );
305
+ const update = K.useCallback(
306
+ async (id, payload) => {
307
+ const updated = await api.updateFolder(id, payload);
308
+ setFolders((prev) => prev.map((f) => f.id === id ? updated : f));
309
+ return updated;
310
+ },
311
+ [api]
312
+ );
313
+ const remove = K.useCallback(
314
+ async (id) => {
315
+ await api.deleteFolder(id);
316
+ setFolders((prev) => prev.filter((f) => f.id !== id));
317
+ },
318
+ [api]
319
+ );
320
+ K.useEffect(() => {
321
+ fetchFolders();
322
+ fetchTree();
323
+ }, []);
324
+ const { durationFetch } = useNotesKitContext();
325
+ K.useEffect(() => {
326
+ if (!durationFetch) return;
327
+ const id = setInterval(() => {
328
+ api.listFolders().then((res) => setFolders(res)).catch(() => {
329
+ });
330
+ api.getFolderTree().then((res) => setTree(res)).catch(() => {
331
+ });
332
+ }, durationFetch);
333
+ return () => clearInterval(id);
334
+ }, [api, durationFetch]);
335
+ return { folders, tree, loading, error, fetchFolders, fetchTree, getFolder, getChildren, create, update, remove };
336
+ }
337
+
338
+ function SearchBar({ value, onChange, placeholder = "\u041D\u0430\u0439\u0442\u0438 \u0437\u0430\u043C\u0435\u0442\u043A\u0443\u2026" }) {
339
+ const { api } = useNotesKitContext();
340
+ const [local, setLocal] = K.useState(value);
341
+ const [suggestions, setSuggestions] = K.useState([]);
342
+ const [showSuggestions, setShowSuggestions] = K.useState(false);
343
+ const [activeIndex, setActiveIndex] = K.useState(-1);
344
+ const searchTimerRef = K.useRef();
345
+ const suggestTimerRef = K.useRef();
346
+ const wrapRef = K.useRef(null);
347
+ K.useEffect(() => {
348
+ const handler = (e) => {
349
+ if (wrapRef.current && !wrapRef.current.contains(e.target)) {
350
+ setShowSuggestions(false);
351
+ }
352
+ };
353
+ document.addEventListener("mousedown", handler);
354
+ return () => document.removeEventListener("mousedown", handler);
355
+ }, []);
356
+ const suggestSeqRef = K.useRef(0);
357
+ const fetchSuggestions = K.useCallback(
358
+ (text) => {
359
+ var _a;
360
+ clearTimeout(suggestTimerRef.current);
361
+ const words = text.trim().split(/\s+/);
362
+ const lastWord = (_a = words[words.length - 1]) != null ? _a : "";
363
+ if (lastWord.length < 2) {
364
+ suggestSeqRef.current++;
365
+ setSuggestions([]);
366
+ setShowSuggestions(false);
367
+ return;
368
+ }
369
+ const seq = ++suggestSeqRef.current;
370
+ suggestTimerRef.current = setTimeout(async () => {
371
+ try {
372
+ const result = await api.suggest(lastWord, 5);
373
+ if (seq !== suggestSeqRef.current) return;
374
+ setSuggestions(result);
375
+ setShowSuggestions(result.length > 0);
376
+ setActiveIndex(-1);
377
+ } catch (e) {
378
+ if (seq !== suggestSeqRef.current) return;
379
+ setSuggestions([]);
380
+ setShowSuggestions(false);
381
+ }
382
+ }, 200);
383
+ },
384
+ [api]
385
+ );
386
+ const handleChange = K.useCallback(
387
+ (e) => {
388
+ const v = e.target.value;
389
+ setLocal(v);
390
+ fetchSuggestions(v);
391
+ clearTimeout(searchTimerRef.current);
392
+ searchTimerRef.current = setTimeout(() => onChange(v), 300);
393
+ },
394
+ [onChange, fetchSuggestions]
395
+ );
396
+ const applySuggestion = K.useCallback(
397
+ (word) => {
398
+ const words = local.trim().split(/\s+/);
399
+ words[words.length - 1] = word;
400
+ const newValue = words.join(" ");
401
+ setLocal(newValue);
402
+ setSuggestions([]);
403
+ setShowSuggestions(false);
404
+ onChange(newValue);
405
+ },
406
+ [local, onChange]
407
+ );
408
+ const handleKeyDown = K.useCallback(
409
+ (e) => {
410
+ if (!showSuggestions || suggestions.length === 0) return;
411
+ if (e.key === "ArrowDown") {
412
+ e.preventDefault();
413
+ setActiveIndex((i) => i < suggestions.length - 1 ? i + 1 : 0);
414
+ } else if (e.key === "ArrowUp") {
415
+ e.preventDefault();
416
+ setActiveIndex((i) => i > 0 ? i - 1 : suggestions.length - 1);
417
+ } else if (e.key === "Enter" && activeIndex >= 0) {
418
+ e.preventDefault();
419
+ applySuggestion(suggestions[activeIndex]);
420
+ } else if (e.key === "Escape") {
421
+ setShowSuggestions(false);
422
+ }
423
+ },
424
+ [showSuggestions, suggestions, activeIndex, applySuggestion]
425
+ );
426
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-search-wrap", ref: wrapRef, children: [
427
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "nk-search-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
428
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "8" }),
429
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m21 21-4.3-4.3" })
430
+ ] }),
431
+ /* @__PURE__ */ jsxRuntime.jsx(
432
+ "input",
433
+ {
434
+ className: "nk-search",
435
+ type: "text",
436
+ value: local,
437
+ onChange: handleChange,
438
+ onKeyDown: handleKeyDown,
439
+ onFocus: () => suggestions.length > 0 && setShowSuggestions(true),
440
+ placeholder,
441
+ autoComplete: "off"
442
+ }
443
+ ),
444
+ showSuggestions && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "nk-suggest", children: suggestions.map((word, i) => /* @__PURE__ */ jsxRuntime.jsx(
445
+ "li",
446
+ {
447
+ className: `nk-suggest__item ${i === activeIndex ? "nk-suggest__item--active" : ""}`,
448
+ onMouseDown: () => applySuggestion(word),
449
+ onMouseEnter: () => setActiveIndex(i),
450
+ children: word
451
+ },
452
+ word
453
+ )) })
454
+ ] });
455
+ }
456
+
457
+ function formatDate(dateStr) {
458
+ const d = new Date(dateStr);
459
+ const dd = String(d.getDate()).padStart(2, "0");
460
+ const mm = String(d.getMonth() + 1).padStart(2, "0");
461
+ const yyyy = d.getFullYear();
462
+ const hh = String(d.getHours()).padStart(2, "0");
463
+ const min = String(d.getMinutes()).padStart(2, "0");
464
+ return `${dd}.${mm}.${yyyy} ${hh}:${min}`;
465
+ }
466
+ function NoteCard({
467
+ note,
468
+ onEdit,
469
+ onDelete,
470
+ onMove,
471
+ onClone
472
+ }) {
473
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-card", onClick: () => onEdit(note), children: [
474
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "nk-card__title", children: note.title || "\u0411\u0435\u0437 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430" }),
475
+ note.content && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "nk-card__preview", children: note.content }),
476
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-card__meta", children: [
477
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
478
+ formatDate(note.createdAt),
479
+ formatDate(note.updatedAt) !== formatDate(note.createdAt) && ` \xB7 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u043E: ${formatDate(note.updatedAt)}`
480
+ ] }),
481
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-card__actions", children: !note.isSystem && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
482
+ /* @__PURE__ */ jsxRuntime.jsx(
483
+ "button",
484
+ {
485
+ className: "nk-btn nk-btn--ghost nk-btn--sm",
486
+ title: "\u041F\u0435\u0440\u0435\u043C\u0435\u0441\u0442\u0438\u0442\u044C \u0432 \u043F\u0430\u043F\u043A\u0443",
487
+ onClick: (e) => {
488
+ e.stopPropagation();
489
+ onMove(note);
490
+ },
491
+ children: "\u21C4"
492
+ }
493
+ ),
494
+ /* @__PURE__ */ jsxRuntime.jsx(
495
+ "button",
496
+ {
497
+ className: "nk-btn nk-btn--ghost nk-btn--sm",
498
+ title: "\u041A\u043B\u043E\u043D\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0432 \u043F\u0430\u043F\u043A\u0443",
499
+ onClick: (e) => {
500
+ e.stopPropagation();
501
+ onClone(note);
502
+ },
503
+ children: "\u2398"
504
+ }
505
+ ),
506
+ /* @__PURE__ */ jsxRuntime.jsx(
507
+ "button",
508
+ {
509
+ className: "nk-btn nk-btn--danger nk-btn--sm",
510
+ title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C",
511
+ onClick: (e) => {
512
+ e.stopPropagation();
513
+ onDelete(note);
514
+ },
515
+ children: "\u2715"
516
+ }
517
+ )
518
+ ] }) })
519
+ ] })
520
+ ] });
521
+ }
522
+
523
+ function _arrayLikeToArray(r, a) {
524
+ (null == a || a > r.length) && (a = r.length);
525
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
526
+ return n;
527
+ }
528
+ function _arrayWithHoles(r) {
529
+ if (Array.isArray(r)) return r;
530
+ }
531
+ function _defineProperty$1(e, r, t) {
532
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
533
+ value: t,
534
+ enumerable: true,
535
+ configurable: true,
536
+ writable: true
537
+ }) : e[r] = t, e;
538
+ }
539
+ function _iterableToArrayLimit(r, l) {
540
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
541
+ if (null != t) {
542
+ var e,
543
+ n,
544
+ i,
545
+ u,
546
+ a = [],
547
+ f = true,
548
+ o = false;
549
+ try {
550
+ if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
551
+ } catch (r) {
552
+ o = true, n = r;
553
+ } finally {
554
+ try {
555
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
556
+ } finally {
557
+ if (o) throw n;
558
+ }
559
+ }
560
+ return a;
561
+ }
562
+ }
563
+ function _nonIterableRest() {
564
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
565
+ }
566
+ function ownKeys$1(e, r) {
567
+ var t = Object.keys(e);
568
+ if (Object.getOwnPropertySymbols) {
569
+ var o = Object.getOwnPropertySymbols(e);
570
+ r && (o = o.filter(function (r) {
571
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
572
+ })), t.push.apply(t, o);
573
+ }
574
+ return t;
575
+ }
576
+ function _objectSpread2$1(e) {
577
+ for (var r = 1; r < arguments.length; r++) {
578
+ var t = null != arguments[r] ? arguments[r] : {};
579
+ r % 2 ? ownKeys$1(Object(t), true).forEach(function (r) {
580
+ _defineProperty$1(e, r, t[r]);
581
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$1(Object(t)).forEach(function (r) {
582
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
583
+ });
584
+ }
585
+ return e;
586
+ }
587
+ function _objectWithoutProperties(e, t) {
588
+ if (null == e) return {};
589
+ var o,
590
+ r,
591
+ i = _objectWithoutPropertiesLoose(e, t);
592
+ if (Object.getOwnPropertySymbols) {
593
+ var n = Object.getOwnPropertySymbols(e);
594
+ for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
595
+ }
596
+ return i;
597
+ }
598
+ function _objectWithoutPropertiesLoose(r, e) {
599
+ if (null == r) return {};
600
+ var t = {};
601
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
602
+ if (-1 !== e.indexOf(n)) continue;
603
+ t[n] = r[n];
604
+ }
605
+ return t;
606
+ }
607
+ function _slicedToArray(r, e) {
608
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
609
+ }
610
+ function _toPrimitive(t, r) {
611
+ if ("object" != typeof t || !t) return t;
612
+ var e = t[Symbol.toPrimitive];
613
+ if (void 0 !== e) {
614
+ var i = e.call(t, r);
615
+ if ("object" != typeof i) return i;
616
+ throw new TypeError("@@toPrimitive must return a primitive value.");
617
+ }
618
+ return ("string" === r ? String : Number)(t);
619
+ }
620
+ function _toPropertyKey(t) {
621
+ var i = _toPrimitive(t, "string");
622
+ return "symbol" == typeof i ? i : i + "";
623
+ }
624
+ function _unsupportedIterableToArray(r, a) {
625
+ if (r) {
626
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
627
+ var t = {}.toString.call(r).slice(8, -1);
628
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
629
+ }
630
+ }
631
+
632
+ function _defineProperty(obj, key, value) {
633
+ if (key in obj) {
634
+ Object.defineProperty(obj, key, {
635
+ value: value,
636
+ enumerable: true,
637
+ configurable: true,
638
+ writable: true
639
+ });
640
+ } else {
641
+ obj[key] = value;
642
+ }
643
+
644
+ return obj;
645
+ }
646
+
647
+ function ownKeys(object, enumerableOnly) {
648
+ var keys = Object.keys(object);
649
+
650
+ if (Object.getOwnPropertySymbols) {
651
+ var symbols = Object.getOwnPropertySymbols(object);
652
+ if (enumerableOnly) symbols = symbols.filter(function (sym) {
653
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
654
+ });
655
+ keys.push.apply(keys, symbols);
656
+ }
657
+
658
+ return keys;
659
+ }
660
+
661
+ function _objectSpread2(target) {
662
+ for (var i = 1; i < arguments.length; i++) {
663
+ var source = arguments[i] != null ? arguments[i] : {};
664
+
665
+ if (i % 2) {
666
+ ownKeys(Object(source), true).forEach(function (key) {
667
+ _defineProperty(target, key, source[key]);
668
+ });
669
+ } else if (Object.getOwnPropertyDescriptors) {
670
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
671
+ } else {
672
+ ownKeys(Object(source)).forEach(function (key) {
673
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
674
+ });
675
+ }
676
+ }
677
+
678
+ return target;
679
+ }
680
+
681
+ function compose$1() {
682
+ for (var _len = arguments.length, fns = new Array(_len), _key = 0; _key < _len; _key++) {
683
+ fns[_key] = arguments[_key];
684
+ }
685
+
686
+ return function (x) {
687
+ return fns.reduceRight(function (y, f) {
688
+ return f(y);
689
+ }, x);
690
+ };
691
+ }
692
+
693
+ function curry$1(fn) {
694
+ return function curried() {
695
+ var _this = this;
696
+
697
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
698
+ args[_key2] = arguments[_key2];
699
+ }
700
+
701
+ return args.length >= fn.length ? fn.apply(this, args) : function () {
702
+ for (var _len3 = arguments.length, nextArgs = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
703
+ nextArgs[_key3] = arguments[_key3];
704
+ }
705
+
706
+ return curried.apply(_this, [].concat(args, nextArgs));
707
+ };
708
+ };
709
+ }
710
+
711
+ function isObject$1(value) {
712
+ return {}.toString.call(value).includes('Object');
713
+ }
714
+
715
+ function isEmpty(obj) {
716
+ return !Object.keys(obj).length;
717
+ }
718
+
719
+ function isFunction(value) {
720
+ return typeof value === 'function';
721
+ }
722
+
723
+ function hasOwnProperty(object, property) {
724
+ return Object.prototype.hasOwnProperty.call(object, property);
725
+ }
726
+
727
+ function validateChanges(initial, changes) {
728
+ if (!isObject$1(changes)) errorHandler$1('changeType');
729
+ if (Object.keys(changes).some(function (field) {
730
+ return !hasOwnProperty(initial, field);
731
+ })) errorHandler$1('changeField');
732
+ return changes;
733
+ }
734
+
735
+ function validateSelector(selector) {
736
+ if (!isFunction(selector)) errorHandler$1('selectorType');
737
+ }
738
+
739
+ function validateHandler(handler) {
740
+ if (!(isFunction(handler) || isObject$1(handler))) errorHandler$1('handlerType');
741
+ if (isObject$1(handler) && Object.values(handler).some(function (_handler) {
742
+ return !isFunction(_handler);
743
+ })) errorHandler$1('handlersType');
744
+ }
745
+
746
+ function validateInitial(initial) {
747
+ if (!initial) errorHandler$1('initialIsRequired');
748
+ if (!isObject$1(initial)) errorHandler$1('initialType');
749
+ if (isEmpty(initial)) errorHandler$1('initialContent');
750
+ }
751
+
752
+ function throwError$1(errorMessages, type) {
753
+ throw new Error(errorMessages[type] || errorMessages["default"]);
754
+ }
755
+
756
+ var errorMessages$1 = {
757
+ initialIsRequired: 'initial state is required',
758
+ initialType: 'initial state should be an object',
759
+ initialContent: 'initial state shouldn\'t be an empty object',
760
+ handlerType: 'handler should be an object or a function',
761
+ handlersType: 'all handlers should be a functions',
762
+ selectorType: 'selector should be a function',
763
+ changeType: 'provided value of changes should be an object',
764
+ changeField: 'it seams you want to change a field in the state which is not specified in the "initial" state',
765
+ "default": 'an unknown error accured in `state-local` package'
766
+ };
767
+ var errorHandler$1 = curry$1(throwError$1)(errorMessages$1);
768
+ var validators$1 = {
769
+ changes: validateChanges,
770
+ selector: validateSelector,
771
+ handler: validateHandler,
772
+ initial: validateInitial
773
+ };
774
+
775
+ function create(initial) {
776
+ var handler = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
777
+ validators$1.initial(initial);
778
+ validators$1.handler(handler);
779
+ var state = {
780
+ current: initial
781
+ };
782
+ var didUpdate = curry$1(didStateUpdate)(state, handler);
783
+ var update = curry$1(updateState)(state);
784
+ var validate = curry$1(validators$1.changes)(initial);
785
+ var getChanges = curry$1(extractChanges)(state);
786
+
787
+ function getState() {
788
+ var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function (state) {
789
+ return state;
790
+ };
791
+ validators$1.selector(selector);
792
+ return selector(state.current);
793
+ }
794
+
795
+ function setState(causedChanges) {
796
+ compose$1(didUpdate, update, validate, getChanges)(causedChanges);
797
+ }
798
+
799
+ return [getState, setState];
800
+ }
801
+
802
+ function extractChanges(state, causedChanges) {
803
+ return isFunction(causedChanges) ? causedChanges(state.current) : causedChanges;
804
+ }
805
+
806
+ function updateState(state, changes) {
807
+ state.current = _objectSpread2(_objectSpread2({}, state.current), changes);
808
+ return changes;
809
+ }
810
+
811
+ function didStateUpdate(state, handler, changes) {
812
+ isFunction(handler) ? handler(state.current) : Object.keys(changes).forEach(function (field) {
813
+ var _handler$field;
814
+
815
+ return (_handler$field = handler[field]) === null || _handler$field === void 0 ? void 0 : _handler$field.call(handler, state.current[field]);
816
+ });
817
+ return changes;
818
+ }
819
+
820
+ var index = {
821
+ create: create
822
+ };
823
+
824
+ var config$1 = {
825
+ paths: {
826
+ vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.55.1/min/vs'
827
+ }
828
+ };
829
+
830
+ function curry(fn) {
831
+ return function curried() {
832
+ var _this = this;
833
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
834
+ args[_key] = arguments[_key];
835
+ }
836
+ return args.length >= fn.length ? fn.apply(this, args) : function () {
837
+ for (var _len2 = arguments.length, nextArgs = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
838
+ nextArgs[_key2] = arguments[_key2];
839
+ }
840
+ return curried.apply(_this, [].concat(args, nextArgs));
841
+ };
842
+ };
843
+ }
844
+
845
+ function isObject(value) {
846
+ return {}.toString.call(value).includes('Object');
847
+ }
848
+
849
+ /**
850
+ * validates the configuration object and informs about deprecation
851
+ * @param {Object} config - the configuration object
852
+ * @return {Object} config - the validated configuration object
853
+ */
854
+ function validateConfig(config) {
855
+ if (!config) errorHandler('configIsRequired');
856
+ if (!isObject(config)) errorHandler('configType');
857
+ if (config.urls) {
858
+ informAboutDeprecation();
859
+ return {
860
+ paths: {
861
+ vs: config.urls.monacoBase
862
+ }
863
+ };
864
+ }
865
+ return config;
866
+ }
867
+
868
+ /**
869
+ * logs deprecation message
870
+ */
871
+ function informAboutDeprecation() {
872
+ console.warn(errorMessages.deprecation);
873
+ }
874
+ function throwError(errorMessages, type) {
875
+ throw new Error(errorMessages[type] || errorMessages["default"]);
876
+ }
877
+ var errorMessages = {
878
+ configIsRequired: 'the configuration object is required',
879
+ configType: 'the configuration object should be an object',
880
+ "default": 'an unknown error accured in `@monaco-editor/loader` package',
881
+ deprecation: "Deprecation warning!\n You are using deprecated way of configuration.\n\n Instead of using\n monaco.config({ urls: { monacoBase: '...' } })\n use\n monaco.config({ paths: { vs: '...' } })\n\n For more please check the link https://github.com/suren-atoyan/monaco-loader#config\n "
882
+ };
883
+ var errorHandler = curry(throwError)(errorMessages);
884
+ var validators = {
885
+ config: validateConfig
886
+ };
887
+
888
+ var compose = function compose() {
889
+ for (var _len = arguments.length, fns = new Array(_len), _key = 0; _key < _len; _key++) {
890
+ fns[_key] = arguments[_key];
891
+ }
892
+ return function (x) {
893
+ return fns.reduceRight(function (y, f) {
894
+ return f(y);
895
+ }, x);
896
+ };
897
+ };
898
+
899
+ function merge(target, source) {
900
+ Object.keys(source).forEach(function (key) {
901
+ if (source[key] instanceof Object) {
902
+ if (target[key]) {
903
+ Object.assign(source[key], merge(target[key], source[key]));
904
+ }
905
+ }
906
+ });
907
+ return _objectSpread2$1(_objectSpread2$1({}, target), source);
908
+ }
909
+
910
+ // The source (has been changed) is https://github.com/facebook/react/issues/5465#issuecomment-157888325
911
+
912
+ var CANCELATION_MESSAGE = {
913
+ type: 'cancelation',
914
+ msg: 'operation is manually canceled'
915
+ };
916
+ function makeCancelable(promise) {
917
+ var hasCanceled_ = false;
918
+ var wrappedPromise = new Promise(function (resolve, reject) {
919
+ promise.then(function (val) {
920
+ return hasCanceled_ ? reject(CANCELATION_MESSAGE) : resolve(val);
921
+ });
922
+ promise["catch"](reject);
923
+ });
924
+ return wrappedPromise.cancel = function () {
925
+ return hasCanceled_ = true;
926
+ }, wrappedPromise;
927
+ }
928
+
929
+ var _excluded = ["monaco"];
930
+
931
+ /** the local state of the module */
932
+ var _state$create = index.create({
933
+ config: config$1,
934
+ isInitialized: false,
935
+ resolve: null,
936
+ reject: null,
937
+ monaco: null
938
+ }),
939
+ _state$create2 = _slicedToArray(_state$create, 2),
940
+ getState = _state$create2[0],
941
+ setState = _state$create2[1];
942
+
943
+ /**
944
+ * set the loader configuration
945
+ * @param {Object} config - the configuration object
946
+ */
947
+ function config(globalConfig) {
948
+ var _validators$config = validators.config(globalConfig),
949
+ monaco = _validators$config.monaco,
950
+ config = _objectWithoutProperties(_validators$config, _excluded);
951
+ setState(function (state) {
952
+ return {
953
+ config: merge(state.config, config),
954
+ monaco: monaco
955
+ };
956
+ });
957
+ }
958
+
959
+ /**
960
+ * handles the initialization of the monaco-editor
961
+ * @return {Promise} - returns an instance of monaco (with a cancelable promise)
962
+ */
963
+ function init() {
964
+ var state = getState(function (_ref) {
965
+ var monaco = _ref.monaco,
966
+ isInitialized = _ref.isInitialized,
967
+ resolve = _ref.resolve;
968
+ return {
969
+ monaco: monaco,
970
+ isInitialized: isInitialized,
971
+ resolve: resolve
972
+ };
973
+ });
974
+ if (!state.isInitialized) {
975
+ setState({
976
+ isInitialized: true
977
+ });
978
+ if (state.monaco) {
979
+ state.resolve(state.monaco);
980
+ return makeCancelable(wrapperPromise);
981
+ }
982
+ if (window.monaco && window.monaco.editor) {
983
+ storeMonacoInstance(window.monaco);
984
+ state.resolve(window.monaco);
985
+ return makeCancelable(wrapperPromise);
986
+ }
987
+ compose(injectScripts, getMonacoLoaderScript)(configureLoader);
988
+ }
989
+ return makeCancelable(wrapperPromise);
990
+ }
991
+
992
+ /**
993
+ * injects provided scripts into the document.body
994
+ * @param {Object} script - an HTML script element
995
+ * @return {Object} - the injected HTML script element
996
+ */
997
+ function injectScripts(script) {
998
+ return document.body.appendChild(script);
999
+ }
1000
+
1001
+ /**
1002
+ * creates an HTML script element with/without provided src
1003
+ * @param {string} [src] - the source path of the script
1004
+ * @return {Object} - the created HTML script element
1005
+ */
1006
+ function createScript(src) {
1007
+ var script = document.createElement('script');
1008
+ return src && (script.src = src), script;
1009
+ }
1010
+
1011
+ /**
1012
+ * creates an HTML script element with the monaco loader src
1013
+ * @return {Object} - the created HTML script element
1014
+ */
1015
+ function getMonacoLoaderScript(configureLoader) {
1016
+ var state = getState(function (_ref2) {
1017
+ var config = _ref2.config,
1018
+ reject = _ref2.reject;
1019
+ return {
1020
+ config: config,
1021
+ reject: reject
1022
+ };
1023
+ });
1024
+ var loaderScript = createScript("".concat(state.config.paths.vs, "/loader.js"));
1025
+ loaderScript.onload = function () {
1026
+ return configureLoader();
1027
+ };
1028
+ loaderScript.onerror = state.reject;
1029
+ return loaderScript;
1030
+ }
1031
+
1032
+ /**
1033
+ * configures the monaco loader
1034
+ */
1035
+ function configureLoader() {
1036
+ var state = getState(function (_ref3) {
1037
+ var config = _ref3.config,
1038
+ resolve = _ref3.resolve,
1039
+ reject = _ref3.reject;
1040
+ return {
1041
+ config: config,
1042
+ resolve: resolve,
1043
+ reject: reject
1044
+ };
1045
+ });
1046
+ var require = window.require;
1047
+ require.config(state.config);
1048
+ require(['vs/editor/editor.main'], function (loaded) {
1049
+ var monaco = loaded.m /* for 0.53 & 0.54 */ || loaded /* for other versions */;
1050
+ storeMonacoInstance(monaco);
1051
+ state.resolve(monaco);
1052
+ }, function (error) {
1053
+ state.reject(error);
1054
+ });
1055
+ }
1056
+
1057
+ /**
1058
+ * store monaco instance in local state
1059
+ */
1060
+ function storeMonacoInstance(monaco) {
1061
+ if (!getState().monaco) {
1062
+ setState({
1063
+ monaco: monaco
1064
+ });
1065
+ }
1066
+ }
1067
+
1068
+ /**
1069
+ * internal helper function
1070
+ * extracts stored monaco instance
1071
+ * @return {Object|null} - the monaco instance
1072
+ */
1073
+ function __getMonacoInstance() {
1074
+ return getState(function (_ref4) {
1075
+ var monaco = _ref4.monaco;
1076
+ return monaco;
1077
+ });
1078
+ }
1079
+ var wrapperPromise = new Promise(function (resolve, reject) {
1080
+ return setState({
1081
+ resolve: resolve,
1082
+ reject: reject
1083
+ });
1084
+ });
1085
+ var loader = {
1086
+ config: config,
1087
+ init: init,
1088
+ __getMonacoInstance: __getMonacoInstance
1089
+ };
1090
+
1091
+ var le={wrapper:{display:"flex",position:"relative",textAlign:"initial"},fullWidth:{width:"100%"},hide:{display:"none"}},v=le;var ae={container:{display:"flex",height:"100%",width:"100%",justifyContent:"center",alignItems:"center"}},Y=ae;function Me({children:e}){return K.createElement("div",{style:Y.container},e)}var Z=Me;var $=Z;function Ee({width:e,height:r,isEditorReady:n,loading:t,_ref:a,className:m,wrapperProps:E}){return K.createElement("section",{style:{...v.wrapper,width:e,height:r},...E},!n&&K.createElement($,null,t),K.createElement("div",{ref:a,style:{...v.fullWidth,...!n&&v.hide},className:m}))}var ee=Ee;var H=K.memo(ee);function Ce(e){K.useEffect(e,[]);}var k=Ce;function he(e,r,n=true){let t=K.useRef(true);K.useEffect(t.current||!n?()=>{t.current=false;}:e,r);}var l=he;function D(){}function h(e,r,n,t){return De(e,t)||be(e,r,n,t)}function De(e,r){return e.editor.getModel(te(e,r))}function be(e,r,n,t){return e.editor.createModel(r,n,t?te(e,t):void 0)}function te(e,r){return e.Uri.parse(r)}function Oe({original:e,modified:r,language:n,originalLanguage:t,modifiedLanguage:a,originalModelPath:m,modifiedModelPath:E,keepCurrentOriginalModel:g=false,keepCurrentModifiedModel:N=false,theme:x="light",loading:P="Loading...",options:y={},height:V="100%",width:z="100%",className:F,wrapperProps:j={},beforeMount:A=D,onMount:q=D}){let[M,O]=K.useState(false),[T,s]=K.useState(true),u=K.useRef(null),c=K.useRef(null),w=K.useRef(null),d=K.useRef(q),o=K.useRef(A),b=K.useRef(false);k(()=>{let i=loader.init();return i.then(f=>(c.current=f)&&s(false)).catch(f=>f?.type!=="cancelation"&&console.error("Monaco initialization: error:",f)),()=>u.current?I():i.cancel()}),l(()=>{if(u.current&&c.current){let i=u.current.getOriginalEditor(),f=h(c.current,e||"",t||n||"text",m||"");f!==i.getModel()&&i.setModel(f);}},[m],M),l(()=>{if(u.current&&c.current){let i=u.current.getModifiedEditor(),f=h(c.current,r||"",a||n||"text",E||"");f!==i.getModel()&&i.setModel(f);}},[E],M),l(()=>{let i=u.current.getModifiedEditor();i.getOption(c.current.editor.EditorOption.readOnly)?i.setValue(r||""):r!==i.getValue()&&(i.executeEdits("",[{range:i.getModel().getFullModelRange(),text:r||"",forceMoveMarkers:true}]),i.pushUndoStop());},[r],M),l(()=>{u.current?.getModel()?.original.setValue(e||"");},[e],M),l(()=>{let{original:i,modified:f}=u.current.getModel();c.current.editor.setModelLanguage(i,t||n||"text"),c.current.editor.setModelLanguage(f,a||n||"text");},[n,t,a],M),l(()=>{c.current?.editor.setTheme(x);},[x],M),l(()=>{u.current?.updateOptions(y);},[y],M);let L=K.useCallback(()=>{if(!c.current)return;o.current(c.current);let i=h(c.current,e||"",t||n||"text",m||""),f=h(c.current,r||"",a||n||"text",E||"");u.current?.setModel({original:i,modified:f});},[n,r,a,e,t,m,E]),U=K.useCallback(()=>{!b.current&&w.current&&(u.current=c.current.editor.createDiffEditor(w.current,{automaticLayout:true,...y}),L(),c.current?.editor.setTheme(x),O(true),b.current=true);},[y,x,L]);K.useEffect(()=>{M&&d.current(u.current,c.current);},[M]),K.useEffect(()=>{!T&&!M&&U();},[T,M,U]);function I(){let i=u.current?.getModel();g||i?.original?.dispose(),N||i?.modified?.dispose(),u.current?.dispose();}return K.createElement(H,{width:z,height:V,isEditorReady:M,loading:P,_ref:w,className:F,wrapperProps:j})}var ie=Oe;K.memo(ie);function He(e){let r=K.useRef();return K.useEffect(()=>{r.current=e;},[e]),r.current}var se=He;var _=new Map;function Ve({defaultValue:e,defaultLanguage:r,defaultPath:n,value:t,language:a,path:m,theme:E="light",line:g,loading:N="Loading...",options:x={},overrideServices:P={},saveViewState:y=true,keepCurrentModel:V=false,width:z="100%",height:F="100%",className:j,wrapperProps:A={},beforeMount:q=D,onMount:M=D,onChange:O,onValidate:T=D}){let[s,u]=K.useState(false),[c,w]=K.useState(true),d=K.useRef(null),o=K.useRef(null),b=K.useRef(null),L=K.useRef(M),U=K.useRef(q),I=K.useRef(),i=K.useRef(t),f=se(m),Q=K.useRef(false),B=K.useRef(false);k(()=>{let p=loader.init();return p.then(R=>(d.current=R)&&w(false)).catch(R=>R?.type!=="cancelation"&&console.error("Monaco initialization: error:",R)),()=>o.current?pe():p.cancel()}),l(()=>{let p=h(d.current,e||t||"",r||a||"",m||n||"");p!==o.current?.getModel()&&(y&&_.set(f,o.current?.saveViewState()),o.current?.setModel(p),y&&o.current?.restoreViewState(_.get(m)));},[m],s),l(()=>{o.current?.updateOptions(x);},[x],s),l(()=>{!o.current||t===void 0||(o.current.getOption(d.current.editor.EditorOption.readOnly)?o.current.setValue(t):t!==o.current.getValue()&&(B.current=true,o.current.executeEdits("",[{range:o.current.getModel().getFullModelRange(),text:t,forceMoveMarkers:true}]),o.current.pushUndoStop(),B.current=false));},[t],s),l(()=>{let p=o.current?.getModel();p&&a&&d.current?.editor.setModelLanguage(p,a);},[a],s),l(()=>{g!==void 0&&o.current?.revealLine(g);},[g],s),l(()=>{d.current?.editor.setTheme(E);},[E],s);let X=K.useCallback(()=>{if(!(!b.current||!d.current)&&!Q.current){U.current(d.current);let p=m||n,R=h(d.current,t||e||"",r||a||"",p||"");o.current=d.current?.editor.create(b.current,{model:R,automaticLayout:true,...x},P),y&&o.current.restoreViewState(_.get(p)),d.current.editor.setTheme(E),g!==void 0&&o.current.revealLine(g),u(true),Q.current=true;}},[e,r,n,t,a,m,x,P,y,E,g]);K.useEffect(()=>{s&&L.current(o.current,d.current);},[s]),K.useEffect(()=>{!c&&!s&&X();},[c,s,X]),i.current=t,K.useEffect(()=>{s&&O&&(I.current?.dispose(),I.current=o.current?.onDidChangeModelContent(p=>{B.current||O(o.current.getValue(),p);}));},[s,O]),K.useEffect(()=>{if(s){let p=d.current.editor.onDidChangeMarkers(R=>{let G=o.current.getModel()?.uri;if(G&&R.find(J=>J.path===G.path)){let J=d.current.editor.getModelMarkers({resource:G});T?.(J);}});return ()=>{p?.dispose();}}return ()=>{}},[s,T]);function pe(){I.current?.dispose(),V?y&&_.set(m,o.current.saveViewState()):o.current.getModel()?.dispose(),o.current.dispose();}return K.createElement(H,{width:z,height:F,isEditorReady:s,loading:N,_ref:b,className:j,wrapperProps:A})}var fe=Ve;var de=K.memo(fe);var Ft=de;
1092
+
1093
+ function NoteEditor({ note, loading, showLineNumbers = false, onSave, onClose }) {
1094
+ var _a;
1095
+ const { theme } = useNotesKitContext();
1096
+ const [title, setTitle] = K.useState("");
1097
+ const [content, setContent] = K.useState("");
1098
+ const [saving, setSaving] = K.useState(false);
1099
+ const [lineNumbers, setLineNumbers] = K.useState(showLineNumbers);
1100
+ const isReadOnly = (_a = note == null ? void 0 : note.isSystem) != null ? _a : false;
1101
+ const titleRef = K.useRef(null);
1102
+ const overlayMouseDown = K.useRef(false);
1103
+ K.useEffect(() => {
1104
+ var _a2, _b;
1105
+ if (loading) return;
1106
+ setTitle((_a2 = note == null ? void 0 : note.title) != null ? _a2 : "");
1107
+ setContent((_b = note == null ? void 0 : note.content) != null ? _b : "");
1108
+ }, [note, loading]);
1109
+ K.useEffect(() => {
1110
+ var _a2;
1111
+ if (!loading) (_a2 = titleRef.current) == null ? void 0 : _a2.focus();
1112
+ }, [loading]);
1113
+ K.useEffect(() => {
1114
+ const handler = (e) => {
1115
+ if (e.key === "Escape") onClose();
1116
+ };
1117
+ window.addEventListener("keydown", handler);
1118
+ return () => window.removeEventListener("keydown", handler);
1119
+ }, [onClose]);
1120
+ const handleSave = K.useCallback(async () => {
1121
+ if (!content.trim()) return;
1122
+ setSaving(true);
1123
+ try {
1124
+ await onSave({ title: title.trim(), content: content.trim() });
1125
+ onClose();
1126
+ } catch (e) {
1127
+ } finally {
1128
+ setSaving(false);
1129
+ }
1130
+ }, [title, content, onSave, onClose]);
1131
+ const handleKeyDown = (e) => {
1132
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
1133
+ handleSave();
1134
+ }
1135
+ };
1136
+ return /* @__PURE__ */ jsxRuntime.jsx(
1137
+ "div",
1138
+ {
1139
+ className: "nk-overlay",
1140
+ onMouseDown: (e) => {
1141
+ if (e.target === e.currentTarget) overlayMouseDown.current = true;
1142
+ },
1143
+ onMouseUp: (e) => {
1144
+ if (e.target === e.currentTarget && overlayMouseDown.current) onClose();
1145
+ overlayMouseDown.current = false;
1146
+ },
1147
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1148
+ "div",
1149
+ {
1150
+ className: "nk-editor",
1151
+ onMouseDown: () => {
1152
+ overlayMouseDown.current = false;
1153
+ },
1154
+ onKeyDown: handleKeyDown,
1155
+ children: [
1156
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-editor__header", children: [
1157
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { children: loading ? "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430\u2026" : isReadOnly ? "\u041F\u0440\u043E\u0441\u043C\u043E\u0442\u0440" : note ? "\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435" : "\u041D\u043E\u0432\u0430\u044F \u0437\u0430\u043C\u0435\u0442\u043A\u0430" }),
1158
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "nk-btn nk-btn--ghost nk-btn--sm", onClick: onClose, children: "\u2715" })
1159
+ ] }),
1160
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-editor__body", style: { display: loading ? "none" : void 0 }, children: [
1161
+ /* @__PURE__ */ jsxRuntime.jsx(
1162
+ "input",
1163
+ {
1164
+ ref: titleRef,
1165
+ className: "nk-input",
1166
+ placeholder: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A",
1167
+ value: title,
1168
+ maxLength: 500,
1169
+ readOnly: isReadOnly,
1170
+ onChange: (e) => {
1171
+ if (!isReadOnly) setTitle(e.target.value);
1172
+ }
1173
+ }
1174
+ ),
1175
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-cm-editor", children: /* @__PURE__ */ jsxRuntime.jsx(
1176
+ Ft,
1177
+ {
1178
+ height: "100%",
1179
+ language: "markdown",
1180
+ theme: theme === "dark" ? "vs-dark" : "light",
1181
+ value: content,
1182
+ onChange: (val) => {
1183
+ if (!isReadOnly) setContent(val != null ? val : "");
1184
+ },
1185
+ options: {
1186
+ readOnly: isReadOnly,
1187
+ fontSize: 14,
1188
+ fontFamily: "'JetBrains Mono', ui-monospace, monospace",
1189
+ lineHeight: 1.6,
1190
+ wordWrap: "on",
1191
+ minimap: { enabled: false },
1192
+ lineNumbers: lineNumbers ? "on" : "off",
1193
+ glyphMargin: false,
1194
+ folding: false,
1195
+ lineDecorationsWidth: 5,
1196
+ lineNumbersMinChars: lineNumbers ? 3 : 0,
1197
+ renderLineHighlight: "none",
1198
+ scrollBeyondLastLine: false,
1199
+ padding: { top: 12, bottom: 12 },
1200
+ placeholder: "\u041D\u0430\u0447\u043D\u0438\u0442\u0435 \u043F\u0438\u0441\u0430\u0442\u044C\u2026 (Markdown)"
1201
+ }
1202
+ }
1203
+ ) })
1204
+ ] }),
1205
+ loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-editor-loading" }),
1206
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-editor__footer", style: { display: loading ? "none" : void 0 }, children: [
1207
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "nk-editor-hint", style: { display: "flex", alignItems: "center", gap: 6, cursor: "pointer" }, children: [
1208
+ /* @__PURE__ */ jsxRuntime.jsx(
1209
+ "input",
1210
+ {
1211
+ type: "checkbox",
1212
+ checked: lineNumbers,
1213
+ onChange: (e) => setLineNumbers(e.target.checked)
1214
+ }
1215
+ ),
1216
+ "\u041D\u0443\u043C\u0435\u0440\u0430\u0446\u0438\u044F \u0441\u0442\u0440\u043E\u043A"
1217
+ ] }),
1218
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-editor-hint", children: "Markdown \xB7 \u043C\u0443\u043B\u044C\u0442\u0438\u043A\u0443\u0440\u0441\u043E\u0440: Ctrl+Click \xB7 Alt+\u043F\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u044C \xB7 Ctrl+D" }),
1219
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "nk-btn nk-btn--ghost", onClick: onClose, children: isReadOnly ? "\u0417\u0430\u043A\u0440\u044B\u0442\u044C" : "\u041E\u0442\u043C\u0435\u043D\u0430" }),
1220
+ !isReadOnly && /* @__PURE__ */ jsxRuntime.jsxs(
1221
+ "button",
1222
+ {
1223
+ className: "nk-btn nk-btn--primary",
1224
+ onClick: handleSave,
1225
+ disabled: saving,
1226
+ children: [
1227
+ saving ? "\u0421\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u0435\u2026" : "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C",
1228
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: 11, opacity: 0.7 }, children: [
1229
+ "Ctrl+",
1230
+ "\u21B5"
1231
+ ] })
1232
+ ]
1233
+ }
1234
+ )
1235
+ ] })
1236
+ ]
1237
+ }
1238
+ )
1239
+ }
1240
+ );
1241
+ }
1242
+
1243
+ function ConfirmDialog({ message, onConfirm, onCancel, loading }) {
1244
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-overlay", onClick: onCancel, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-editor", style: { width: "auto", maxWidth: 420, height: "auto" }, onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-editor__body", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-confirm", children: [
1245
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: message }),
1246
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-confirm__actions", children: [
1247
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "nk-btn nk-btn--ghost", onClick: onCancel, children: "\u041E\u0442\u043C\u0435\u043D\u0430" }),
1248
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "nk-btn nk-btn--danger", onClick: onConfirm, disabled: loading, children: loading ? "\u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435\u2026" : "\u0423\u0434\u0430\u043B\u0438\u0442\u044C" })
1249
+ ] })
1250
+ ] }) }) }) });
1251
+ }
1252
+
1253
+ function buildPageNumbers(current, total) {
1254
+ if (total <= 7) {
1255
+ return Array.from({ length: total }, (_, i) => i);
1256
+ }
1257
+ const pages = /* @__PURE__ */ new Set();
1258
+ pages.add(0);
1259
+ pages.add(total - 1);
1260
+ for (let i = current - 1; i <= current + 1; i++) {
1261
+ if (i >= 0 && i < total) pages.add(i);
1262
+ }
1263
+ const sorted = [...pages].sort((a, b) => a - b);
1264
+ const result = [];
1265
+ for (let i = 0; i < sorted.length; i++) {
1266
+ if (i > 0 && sorted[i] - sorted[i - 1] > 1) {
1267
+ result.push("\u2026");
1268
+ }
1269
+ result.push(sorted[i]);
1270
+ }
1271
+ return result;
1272
+ }
1273
+ function Pagination({
1274
+ currentPage,
1275
+ totalPages,
1276
+ totalElements,
1277
+ pageSize,
1278
+ pageSizeOptions,
1279
+ onPageChange,
1280
+ onPageSizeChange
1281
+ }) {
1282
+ const pages = K.useMemo(() => buildPageNumbers(currentPage, totalPages), [currentPage, totalPages]);
1283
+ K.useEffect(() => {
1284
+ try {
1285
+ localStorage.setItem("nk-page-size", String(pageSize));
1286
+ } catch (e) {
1287
+ }
1288
+ }, [pageSize]);
1289
+ const from = currentPage * pageSize + 1;
1290
+ const to = Math.min((currentPage + 1) * pageSize, totalElements);
1291
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-pagination", children: [
1292
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "nk-pagination__info", children: [
1293
+ from,
1294
+ "\u2013",
1295
+ to,
1296
+ " \u0438\u0437 ",
1297
+ totalElements
1298
+ ] }),
1299
+ /* @__PURE__ */ jsxRuntime.jsx(
1300
+ "select",
1301
+ {
1302
+ className: "nk-pagination__select",
1303
+ value: pageSize,
1304
+ onChange: (e) => onPageSizeChange(Number(e.target.value)),
1305
+ children: pageSizeOptions.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt, children: opt }, opt))
1306
+ }
1307
+ ),
1308
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-pagination__nav", children: [
1309
+ /* @__PURE__ */ jsxRuntime.jsx(
1310
+ "button",
1311
+ {
1312
+ className: "nk-pagination__btn",
1313
+ disabled: currentPage <= 0,
1314
+ onClick: () => onPageChange(currentPage - 1),
1315
+ children: "\u2039"
1316
+ }
1317
+ ),
1318
+ pages.map(
1319
+ (p, i) => p === "\u2026" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-pagination__ellipsis", children: "\u2026" }, `ellipsis-${i}`) : /* @__PURE__ */ jsxRuntime.jsx(
1320
+ "button",
1321
+ {
1322
+ className: `nk-pagination__btn ${p === currentPage ? "nk-pagination__btn--active" : ""}`,
1323
+ onClick: () => onPageChange(p),
1324
+ children: p + 1
1325
+ },
1326
+ p
1327
+ )
1328
+ ),
1329
+ /* @__PURE__ */ jsxRuntime.jsx(
1330
+ "button",
1331
+ {
1332
+ className: "nk-pagination__btn",
1333
+ disabled: currentPage >= totalPages - 1,
1334
+ onClick: () => onPageChange(currentPage + 1),
1335
+ children: "\u203A"
1336
+ }
1337
+ )
1338
+ ] })
1339
+ ] });
1340
+ }
1341
+
1342
+ const SORT_OPTIONS = [
1343
+ { label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A", field: "title" },
1344
+ { label: "\u0421\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0435", field: "content" },
1345
+ { label: "\u0414\u0430\u0442\u0430 \u0441\u043E\u0437\u0434\u0430\u043D\u0438\u044F", field: "createdAt" },
1346
+ { label: "\u0414\u0430\u0442\u0430 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F", field: "updatedAt" }
1347
+ ];
1348
+ const DEFAULT_SORT = "updatedAt,desc";
1349
+ function parseSort(value) {
1350
+ const [field, dir] = value.split(",");
1351
+ return { field, dir: dir === "asc" ? "asc" : "desc" };
1352
+ }
1353
+ function SortBar({ value, onChange }) {
1354
+ const { field: activeField, dir } = parseSort(value);
1355
+ const handleFieldClick = (field) => {
1356
+ if (field === activeField) {
1357
+ onChange(`${field},${dir === "asc" ? "desc" : "asc"}`);
1358
+ } else {
1359
+ onChange(`${field},desc`);
1360
+ }
1361
+ };
1362
+ const isDefault = value === DEFAULT_SORT;
1363
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-sort", children: [
1364
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-sort__label", children: "\u0421\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430:" }),
1365
+ SORT_OPTIONS.map((opt) => {
1366
+ const isActive = opt.field === activeField;
1367
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1368
+ "button",
1369
+ {
1370
+ className: `nk-sort__btn ${isActive ? "nk-sort__btn--active" : ""}`,
1371
+ onClick: () => handleFieldClick(opt.field),
1372
+ children: [
1373
+ opt.label,
1374
+ isActive && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-sort__arrow", children: dir === "asc" ? "\u2191" : "\u2193" })
1375
+ ]
1376
+ },
1377
+ opt.field
1378
+ );
1379
+ }),
1380
+ !isDefault && /* @__PURE__ */ jsxRuntime.jsx(
1381
+ "button",
1382
+ {
1383
+ className: "nk-sort__btn nk-sort__btn--reset",
1384
+ onClick: () => onChange(DEFAULT_SORT),
1385
+ children: "\u0421\u0431\u0440\u043E\u0441"
1386
+ }
1387
+ )
1388
+ ] });
1389
+ }
1390
+
1391
+ function TreeItem({
1392
+ node,
1393
+ depth,
1394
+ selectedFolderId,
1395
+ onSelect,
1396
+ onCreate,
1397
+ onRename,
1398
+ onDelete
1399
+ }) {
1400
+ const [expanded, setExpanded] = K.useState(false);
1401
+ const [editing, setEditing] = K.useState(false);
1402
+ const [editName, setEditName] = K.useState(node.name);
1403
+ const [creating, setCreating] = K.useState(false);
1404
+ const [newName, setNewName] = K.useState("");
1405
+ const [deleting, setDeleting] = K.useState(false);
1406
+ const [deleteLoading, setDeleteLoading] = K.useState(false);
1407
+ const isActive = selectedFolderId === node.id;
1408
+ const hasChildren = node.children.length > 0;
1409
+ const isSystem = node.isSystem;
1410
+ const handleRename = async () => {
1411
+ const trimmed = editName.trim();
1412
+ if (!trimmed || trimmed === node.name) {
1413
+ setEditing(false);
1414
+ setEditName(node.name);
1415
+ return;
1416
+ }
1417
+ await onRename(node.id, { name: trimmed, parentId: node.parentId });
1418
+ setEditing(false);
1419
+ };
1420
+ const handleCreate = async () => {
1421
+ const trimmed = newName.trim();
1422
+ if (!trimmed) {
1423
+ setCreating(false);
1424
+ return;
1425
+ }
1426
+ await onCreate({ name: trimmed, parentId: node.id });
1427
+ setNewName("");
1428
+ setCreating(false);
1429
+ setExpanded(true);
1430
+ };
1431
+ const handleDelete = async () => {
1432
+ setDeleteLoading(true);
1433
+ try {
1434
+ await onDelete(node.id);
1435
+ } finally {
1436
+ setDeleteLoading(false);
1437
+ setDeleting(false);
1438
+ }
1439
+ };
1440
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1441
+ /* @__PURE__ */ jsxRuntime.jsxs(
1442
+ "div",
1443
+ {
1444
+ className: `nk-folder-item ${isActive ? "nk-folder-item--active" : ""}`,
1445
+ style: { paddingLeft: 12 + depth * 16 },
1446
+ onClick: () => {
1447
+ onSelect(node.id);
1448
+ if (hasChildren) setExpanded((e) => !e);
1449
+ },
1450
+ children: [
1451
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "nk-folder__icon", children: [
1452
+ expanded && hasChildren ? "\u{1F4C2}" : "\u{1F4C1}",
1453
+ hasChildren && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-folder__expand-hint", children: expanded ? "\u25BE" : "\u25B8" })
1454
+ ] }),
1455
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
1456
+ "input",
1457
+ {
1458
+ className: "nk-folder-input",
1459
+ value: editName,
1460
+ autoFocus: true,
1461
+ onChange: (e) => setEditName(e.target.value),
1462
+ onKeyDown: (e) => {
1463
+ if (e.key === "Enter") handleRename();
1464
+ if (e.key === "Escape") {
1465
+ setEditing(false);
1466
+ setEditName(node.name);
1467
+ }
1468
+ },
1469
+ onBlur: handleRename,
1470
+ onClick: (e) => e.stopPropagation()
1471
+ }
1472
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-folder__name", children: node.name }),
1473
+ !editing && node.noteCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-folder__badge", children: node.noteCount }),
1474
+ !editing && !isSystem && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-folder__actions", children: [
1475
+ /* @__PURE__ */ jsxRuntime.jsx(
1476
+ "button",
1477
+ {
1478
+ className: "nk-folder__action-btn",
1479
+ title: "\u041F\u0435\u0440\u0435\u0438\u043C\u0435\u043D\u043E\u0432\u0430\u0442\u044C",
1480
+ onClick: (e) => {
1481
+ e.stopPropagation();
1482
+ setEditName(node.name);
1483
+ setEditing(true);
1484
+ },
1485
+ children: "\u270E"
1486
+ }
1487
+ ),
1488
+ /* @__PURE__ */ jsxRuntime.jsx(
1489
+ "button",
1490
+ {
1491
+ className: "nk-folder__action-btn",
1492
+ title: "\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043F\u043E\u0434\u043F\u0430\u043F\u043A\u0443",
1493
+ onClick: (e) => {
1494
+ e.stopPropagation();
1495
+ setCreating(true);
1496
+ setExpanded(true);
1497
+ },
1498
+ children: "+"
1499
+ }
1500
+ ),
1501
+ /* @__PURE__ */ jsxRuntime.jsx(
1502
+ "button",
1503
+ {
1504
+ className: "nk-folder__action-btn nk-folder__action-btn--danger",
1505
+ title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u043F\u0430\u043F\u043A\u0443",
1506
+ onClick: (e) => {
1507
+ e.stopPropagation();
1508
+ setDeleting(true);
1509
+ },
1510
+ children: "\u2715"
1511
+ }
1512
+ )
1513
+ ] })
1514
+ ]
1515
+ }
1516
+ ),
1517
+ expanded && hasChildren && node.children.map((child) => /* @__PURE__ */ jsxRuntime.jsx(
1518
+ TreeItem,
1519
+ {
1520
+ node: child,
1521
+ depth: depth + 1,
1522
+ selectedFolderId,
1523
+ onSelect,
1524
+ onCreate,
1525
+ onRename,
1526
+ onDelete
1527
+ },
1528
+ child.id
1529
+ )),
1530
+ creating && /* @__PURE__ */ jsxRuntime.jsxs(
1531
+ "div",
1532
+ {
1533
+ className: "nk-folder-item",
1534
+ style: { paddingLeft: 12 + (depth + 1) * 16 },
1535
+ children: [
1536
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-folder__icon", children: "\u{1F4C1}" }),
1537
+ /* @__PURE__ */ jsxRuntime.jsx(
1538
+ "input",
1539
+ {
1540
+ className: "nk-folder-input",
1541
+ placeholder: "\u041D\u043E\u0432\u0430\u044F \u043F\u0430\u043F\u043A\u0430\u2026",
1542
+ value: newName,
1543
+ autoFocus: true,
1544
+ onChange: (e) => setNewName(e.target.value),
1545
+ onKeyDown: (e) => {
1546
+ if (e.key === "Enter") handleCreate();
1547
+ if (e.key === "Escape") {
1548
+ setCreating(false);
1549
+ setNewName("");
1550
+ }
1551
+ },
1552
+ onBlur: handleCreate,
1553
+ onClick: (e) => e.stopPropagation()
1554
+ }
1555
+ )
1556
+ ]
1557
+ }
1558
+ ),
1559
+ deleting && /* @__PURE__ */ jsxRuntime.jsx(
1560
+ ConfirmDialog,
1561
+ {
1562
+ message: `\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u043F\u0430\u043F\u043A\u0443 \xAB${node.name}\xBB? \u0417\u0430\u043C\u0435\u0442\u043A\u0438 \u0432\u043D\u0443\u0442\u0440\u0438 \u043E\u0441\u0442\u0430\u043D\u0443\u0442\u0441\u044F \u0431\u0435\u0437 \u043F\u0430\u043F\u043A\u0438.`,
1563
+ onConfirm: handleDelete,
1564
+ onCancel: () => setDeleting(false),
1565
+ loading: deleteLoading
1566
+ }
1567
+ )
1568
+ ] });
1569
+ }
1570
+ function FolderPanel({
1571
+ tree,
1572
+ loading,
1573
+ selectedFolderId,
1574
+ isRootOnly,
1575
+ collapsed,
1576
+ onToggle,
1577
+ onSelectAll,
1578
+ onSelectRootOnly,
1579
+ onSelectFolder,
1580
+ onCreate,
1581
+ onRename,
1582
+ onDelete
1583
+ }) {
1584
+ const [creatingRoot, setCreatingRoot] = K.useState(false);
1585
+ const [rootName, setRootName] = K.useState("");
1586
+ K.useEffect(() => {
1587
+ try {
1588
+ localStorage.setItem(
1589
+ "nk-folder-selection",
1590
+ JSON.stringify({ folderId: selectedFolderId, isRootOnly })
1591
+ );
1592
+ } catch (e) {
1593
+ }
1594
+ }, [selectedFolderId, isRootOnly]);
1595
+ const handleCreateRoot = K.useCallback(async () => {
1596
+ const trimmed = rootName.trim();
1597
+ if (!trimmed) {
1598
+ setCreatingRoot(false);
1599
+ return;
1600
+ }
1601
+ await onCreate({ name: trimmed });
1602
+ setRootName("");
1603
+ setCreatingRoot(false);
1604
+ }, [rootName, onCreate]);
1605
+ const isAll = selectedFolderId === null && !isRootOnly;
1606
+ const isRoot = selectedFolderId === null && isRootOnly;
1607
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `nk-sidebar ${collapsed ? "nk-sidebar--collapsed" : ""}`, children: [
1608
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-sidebar__header", children: [
1609
+ !collapsed && /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u041F\u0430\u043F\u043A\u0438" }),
1610
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-sidebar__header-actions", children: /* @__PURE__ */ jsxRuntime.jsx(
1611
+ "button",
1612
+ {
1613
+ className: "nk-folder__action-btn",
1614
+ title: collapsed ? "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u043F\u0430\u043F\u043A\u0438" : "\u0421\u043A\u0440\u044B\u0442\u044C \u043F\u0430\u043F\u043A\u0438",
1615
+ onClick: onToggle,
1616
+ children: collapsed ? "\u25B8" : "\u25C2"
1617
+ }
1618
+ ) })
1619
+ ] }),
1620
+ !collapsed && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-sidebar__list", children: [
1621
+ /* @__PURE__ */ jsxRuntime.jsxs(
1622
+ "div",
1623
+ {
1624
+ className: `nk-folder-item ${isAll ? "nk-folder-item--active" : ""}`,
1625
+ onClick: onSelectAll,
1626
+ children: [
1627
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-folder__icon", children: "\u{1F4DA}" }),
1628
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-folder__name", children: "\u0412\u0441\u0435 \u0437\u0430\u043C\u0435\u0442\u043A\u0438" })
1629
+ ]
1630
+ }
1631
+ ),
1632
+ /* @__PURE__ */ jsxRuntime.jsxs(
1633
+ "div",
1634
+ {
1635
+ className: `nk-folder-item ${isRoot ? "nk-folder-item--active" : ""}`,
1636
+ onClick: onSelectRootOnly,
1637
+ children: [
1638
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-folder__icon", children: "\u{1F4C4}" }),
1639
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-folder__name", children: "\u0411\u0435\u0437 \u043F\u0430\u043F\u043A\u0438" })
1640
+ ]
1641
+ }
1642
+ ),
1643
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-sidebar__divider" }),
1644
+ loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-sidebar__loading", children: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430\u2026" }) : tree.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-sidebar__empty", children: "\u041D\u0435\u0442 \u043F\u0430\u043F\u043E\u043A" }) : (() => {
1645
+ const systemFolders = tree.filter((n) => n.isSystem);
1646
+ const userFolders = tree.filter((n) => !n.isSystem);
1647
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1648
+ userFolders.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1649
+ systemFolders.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-sidebar__section-label", children: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435" }),
1650
+ userFolders.map((node) => /* @__PURE__ */ jsxRuntime.jsx(
1651
+ TreeItem,
1652
+ {
1653
+ node,
1654
+ depth: 0,
1655
+ selectedFolderId,
1656
+ onSelect: onSelectFolder,
1657
+ onCreate,
1658
+ onRename,
1659
+ onDelete
1660
+ },
1661
+ node.id
1662
+ ))
1663
+ ] }),
1664
+ systemFolders.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-sidebar__divider" }),
1665
+ systemFolders.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1666
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-sidebar__section-label", children: "\u0421\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435" }),
1667
+ systemFolders.map((node) => /* @__PURE__ */ jsxRuntime.jsx(
1668
+ TreeItem,
1669
+ {
1670
+ node,
1671
+ depth: 0,
1672
+ selectedFolderId,
1673
+ onSelect: onSelectFolder,
1674
+ onCreate,
1675
+ onRename,
1676
+ onDelete
1677
+ },
1678
+ node.id
1679
+ ))
1680
+ ] })
1681
+ ] });
1682
+ })(),
1683
+ creatingRoot ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-folder-item nk-folder-item--create", children: [
1684
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-folder__icon", children: "\u{1F4C1}" }),
1685
+ /* @__PURE__ */ jsxRuntime.jsx(
1686
+ "input",
1687
+ {
1688
+ className: "nk-folder-input",
1689
+ placeholder: "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043F\u0430\u043F\u043A\u0438\u2026",
1690
+ value: rootName,
1691
+ autoFocus: true,
1692
+ onChange: (e) => setRootName(e.target.value),
1693
+ onKeyDown: (e) => {
1694
+ if (e.key === "Enter") handleCreateRoot();
1695
+ if (e.key === "Escape") {
1696
+ setCreatingRoot(false);
1697
+ setRootName("");
1698
+ }
1699
+ },
1700
+ onBlur: handleCreateRoot
1701
+ }
1702
+ )
1703
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(
1704
+ "div",
1705
+ {
1706
+ className: "nk-folder-item nk-folder-item--create",
1707
+ onClick: () => setCreatingRoot(true),
1708
+ children: [
1709
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-folder__icon--add", children: "+" }),
1710
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-folder__name", children: "\u041D\u043E\u0432\u0430\u044F \u043F\u0430\u043F\u043A\u0430" })
1711
+ ]
1712
+ }
1713
+ )
1714
+ ] })
1715
+ ] });
1716
+ }
1717
+
1718
+ function PickerTreeItem({
1719
+ node,
1720
+ depth,
1721
+ selected,
1722
+ disabledId,
1723
+ onSelect
1724
+ }) {
1725
+ const [expanded, setExpanded] = K.useState(false);
1726
+ const hasChildren = node.children.length > 0;
1727
+ const isDisabled = node.id === disabledId;
1728
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1729
+ /* @__PURE__ */ jsxRuntime.jsxs(
1730
+ "div",
1731
+ {
1732
+ className: `nk-picker-item ${selected === node.id ? "nk-picker-item--active" : ""} ${isDisabled ? "nk-picker-item--disabled" : ""}`,
1733
+ style: { paddingLeft: 12 + depth * 20 },
1734
+ onClick: () => {
1735
+ if (!isDisabled) onSelect(node.id);
1736
+ },
1737
+ children: [
1738
+ hasChildren && /* @__PURE__ */ jsxRuntime.jsx(
1739
+ "span",
1740
+ {
1741
+ className: `nk-folder__chevron ${expanded ? "nk-folder__chevron--open" : ""}`,
1742
+ onClick: (e) => {
1743
+ e.stopPropagation();
1744
+ setExpanded(!expanded);
1745
+ },
1746
+ children: "\u25B8"
1747
+ }
1748
+ ),
1749
+ !hasChildren && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-folder__chevron nk-folder__chevron--empty" }),
1750
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "nk-picker-item__name", children: [
1751
+ node.name,
1752
+ isDisabled && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-picker-item__current", children: " \u2014 \u0442\u0435\u043A\u0443\u0449\u0430\u044F" })
1753
+ ] })
1754
+ ]
1755
+ }
1756
+ ),
1757
+ expanded && hasChildren && node.children.map((child) => /* @__PURE__ */ jsxRuntime.jsx(
1758
+ PickerTreeItem,
1759
+ {
1760
+ node: child,
1761
+ depth: depth + 1,
1762
+ selected,
1763
+ disabledId,
1764
+ onSelect
1765
+ },
1766
+ child.id
1767
+ ))
1768
+ ] });
1769
+ }
1770
+ function FolderPickerDialog({
1771
+ title,
1772
+ tree,
1773
+ currentFolderId,
1774
+ onConfirm,
1775
+ onCancel,
1776
+ loading
1777
+ }) {
1778
+ const [selected, setSelected] = K.useState(null);
1779
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-overlay", onClick: onCancel, children: /* @__PURE__ */ jsxRuntime.jsx(
1780
+ "div",
1781
+ {
1782
+ className: "nk-editor",
1783
+ style: { width: "auto", maxWidth: 460, height: "auto", maxHeight: "70vh" },
1784
+ onClick: (e) => e.stopPropagation(),
1785
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-editor__body", style: { padding: 0 }, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-picker", children: [
1786
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-picker__header", children: title }),
1787
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-picker__list", children: [
1788
+ /* @__PURE__ */ (() => {
1789
+ const rootDisabled = currentFolderId === null;
1790
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1791
+ "div",
1792
+ {
1793
+ className: `nk-picker-item ${selected === null ? "nk-picker-item--active" : ""} ${rootDisabled ? "nk-picker-item--disabled" : ""}`,
1794
+ style: { paddingLeft: 12 },
1795
+ onClick: () => {
1796
+ if (!rootDisabled) setSelected(null);
1797
+ },
1798
+ children: [
1799
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-folder__chevron nk-folder__chevron--empty" }),
1800
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "nk-picker-item__name", children: [
1801
+ "\u0411\u0435\u0437 \u043F\u0430\u043F\u043A\u0438 (\u043A\u043E\u0440\u0435\u043D\u044C)",
1802
+ rootDisabled && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nk-picker-item__current", children: " \u2014 \u0442\u0435\u043A\u0443\u0449\u0430\u044F" })
1803
+ ] })
1804
+ ]
1805
+ }
1806
+ );
1807
+ })(),
1808
+ tree.map((node) => /* @__PURE__ */ jsxRuntime.jsx(
1809
+ PickerTreeItem,
1810
+ {
1811
+ node,
1812
+ depth: 0,
1813
+ selected,
1814
+ disabledId: currentFolderId,
1815
+ onSelect: setSelected
1816
+ },
1817
+ node.id
1818
+ ))
1819
+ ] }),
1820
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-picker__footer", children: [
1821
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "nk-btn nk-btn--ghost", onClick: onCancel, children: "\u041E\u0442\u043C\u0435\u043D\u0430" }),
1822
+ /* @__PURE__ */ jsxRuntime.jsx(
1823
+ "button",
1824
+ {
1825
+ className: "nk-btn nk-btn--primary",
1826
+ disabled: loading || selected === currentFolderId,
1827
+ onClick: () => onConfirm(selected),
1828
+ children: loading ? "\u041F\u043E\u0434\u043E\u0436\u0434\u0438\u0442\u0435\u2026" : "\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044C"
1829
+ }
1830
+ )
1831
+ ] })
1832
+ ] }) })
1833
+ }
1834
+ ) });
1835
+ }
1836
+
1837
+ function readFolderSelection() {
1838
+ try {
1839
+ const saved = localStorage.getItem("nk-folder-selection");
1840
+ if (saved) return JSON.parse(saved);
1841
+ } catch (e) {
1842
+ }
1843
+ return null;
1844
+ }
1845
+ function readPageSize(defaultSize, options) {
1846
+ try {
1847
+ const saved = localStorage.getItem("nk-page-size");
1848
+ if (saved) {
1849
+ const size = Number(saved);
1850
+ if (options.includes(size)) return size;
1851
+ }
1852
+ } catch (e) {
1853
+ }
1854
+ return defaultSize;
1855
+ }
1856
+ function NotesWidget({
1857
+ pageSize = 12,
1858
+ pageSizeOptions = [12, 20, 40, 60],
1859
+ title = "\u0417\u0430\u043C\u0435\u0442\u043A\u0438",
1860
+ className,
1861
+ folderId,
1862
+ rootOnly
1863
+ }) {
1864
+ var _a, _b, _c, _d, _e;
1865
+ const { api, theme } = useNotesKitContext();
1866
+ const _savedSelection = folderId !== void 0 || rootOnly !== void 0 ? null : readFolderSelection();
1867
+ const [selectedFolderId, setSelectedFolderId] = K.useState((_a = folderId != null ? folderId : _savedSelection == null ? void 0 : _savedSelection.folderId) != null ? _a : null);
1868
+ const [isRootOnly, setIsRootOnly] = K.useState((_b = rootOnly != null ? rootOnly : _savedSelection == null ? void 0 : _savedSelection.isRootOnly) != null ? _b : false);
1869
+ const {
1870
+ notes,
1871
+ totalElements,
1872
+ totalPages,
1873
+ currentPage,
1874
+ loading,
1875
+ error,
1876
+ params,
1877
+ create,
1878
+ update,
1879
+ move,
1880
+ clone,
1881
+ remove,
1882
+ setParams,
1883
+ goToPage,
1884
+ fetch
1885
+ } = useNotes({
1886
+ size: readPageSize(pageSize, pageSizeOptions),
1887
+ folderId: selectedFolderId != null ? selectedFolderId : void 0,
1888
+ rootOnly: isRootOnly || void 0,
1889
+ sort: "updatedAt,desc"
1890
+ });
1891
+ const {
1892
+ tree,
1893
+ loading: foldersLoading,
1894
+ create: createFolder,
1895
+ update: updateFolder,
1896
+ remove: removeFolder,
1897
+ fetchTree
1898
+ } = useFolders();
1899
+ const [sidebarCollapsed, setSidebarCollapsed] = K.useState(false);
1900
+ const [editing, setEditing] = K.useState(void 0);
1901
+ const [editLoading, setEditLoading] = K.useState(false);
1902
+ const [deleting, setDeleting] = K.useState(null);
1903
+ const [deleteLoading, setDeleteLoading] = K.useState(false);
1904
+ const [moving, setMoving] = K.useState(null);
1905
+ const [moveLoading, setMoveLoading] = K.useState(false);
1906
+ const [cloning, setCloning] = K.useState(null);
1907
+ const [cloneLoading, setCloneLoading] = K.useState(false);
1908
+ const handleSelectAll = K.useCallback(() => {
1909
+ setSelectedFolderId(null);
1910
+ setIsRootOnly(false);
1911
+ setParams({ folderId: void 0, rootOnly: void 0, page: 0 });
1912
+ }, [setParams]);
1913
+ const handleSelectRootOnly = K.useCallback(() => {
1914
+ setSelectedFolderId(null);
1915
+ setIsRootOnly(true);
1916
+ setParams({ folderId: void 0, rootOnly: true, page: 0 });
1917
+ }, [setParams]);
1918
+ const handleSelectFolder = K.useCallback((id) => {
1919
+ setSelectedFolderId(id);
1920
+ setIsRootOnly(false);
1921
+ setParams({ folderId: id, rootOnly: void 0, page: 0 });
1922
+ }, [setParams]);
1923
+ const handleCreateFolder = K.useCallback(async (payload) => {
1924
+ const folder = await createFolder(payload);
1925
+ await fetchTree();
1926
+ return folder;
1927
+ }, [createFolder, fetchTree]);
1928
+ const handleRenameFolder = K.useCallback(async (id, payload) => {
1929
+ const folder = await updateFolder(id, payload);
1930
+ await fetchTree();
1931
+ return folder;
1932
+ }, [updateFolder, fetchTree]);
1933
+ const handleDeleteFolder = K.useCallback(async (id) => {
1934
+ await removeFolder(id);
1935
+ if (selectedFolderId === id) handleSelectAll();
1936
+ await fetchTree();
1937
+ await fetch();
1938
+ }, [removeFolder, selectedFolderId, handleSelectAll, fetchTree, fetch]);
1939
+ const handleCardClick = K.useCallback(
1940
+ async (note) => {
1941
+ setEditLoading(true);
1942
+ setEditing(null);
1943
+ try {
1944
+ const full = await api.getNote(note.id);
1945
+ setEditing(full);
1946
+ } catch (e) {
1947
+ setEditing(void 0);
1948
+ } finally {
1949
+ setEditLoading(false);
1950
+ }
1951
+ },
1952
+ [api]
1953
+ );
1954
+ const handleSearch = K.useCallback(
1955
+ (search) => setParams({ search: search || void 0, page: 0 }),
1956
+ [setParams]
1957
+ );
1958
+ const handleSave = K.useCallback(
1959
+ async (payload) => {
1960
+ try {
1961
+ if (editing === null && !editLoading) {
1962
+ await create({ ...payload, folderId: selectedFolderId });
1963
+ } else if (editing) {
1964
+ await update(editing.id, { title: payload.title, content: payload.content });
1965
+ }
1966
+ setEditing(void 0);
1967
+ setEditLoading(false);
1968
+ await fetch();
1969
+ await fetchTree();
1970
+ } catch (e) {
1971
+ setEditing(void 0);
1972
+ setEditLoading(false);
1973
+ }
1974
+ },
1975
+ [editing, editLoading, create, update, fetch, fetchTree, selectedFolderId]
1976
+ );
1977
+ const handleNew = K.useCallback(() => {
1978
+ setEditLoading(false);
1979
+ setEditing(null);
1980
+ }, []);
1981
+ const handleDelete = K.useCallback(async () => {
1982
+ if (!deleting) return;
1983
+ setDeleteLoading(true);
1984
+ try {
1985
+ await remove(deleting.id);
1986
+ setDeleting(null);
1987
+ await fetchTree();
1988
+ } finally {
1989
+ setDeleteLoading(false);
1990
+ }
1991
+ }, [deleting, remove, fetchTree]);
1992
+ const handleMove = K.useCallback(async (folderId2) => {
1993
+ if (!moving) return;
1994
+ setMoveLoading(true);
1995
+ try {
1996
+ await move(moving.id, { folderId: folderId2 });
1997
+ setMoving(null);
1998
+ await fetch();
1999
+ await fetchTree();
2000
+ } finally {
2001
+ setMoveLoading(false);
2002
+ }
2003
+ }, [moving, move, fetch, fetchTree]);
2004
+ const handleClone = K.useCallback(async (folderId2) => {
2005
+ if (!cloning) return;
2006
+ setCloneLoading(true);
2007
+ try {
2008
+ await clone(cloning.id, { folderId: folderId2 });
2009
+ setCloning(null);
2010
+ await fetch();
2011
+ await fetchTree();
2012
+ } finally {
2013
+ setCloneLoading(false);
2014
+ }
2015
+ }, [cloning, clone, fetch, fetchTree]);
2016
+ const handlePageSizeChange = K.useCallback(
2017
+ (newSize) => setParams({ size: newSize, page: 0 }),
2018
+ [setParams]
2019
+ );
2020
+ const handleSortChange = K.useCallback(
2021
+ (sort) => setParams({ sort, page: 0 }),
2022
+ [setParams]
2023
+ );
2024
+ const isEditorOpen = editing !== void 0 || editLoading;
2025
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `nk-root ${className != null ? className : ""}`, "data-theme": theme, children: [
2026
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-layout", children: [
2027
+ /* @__PURE__ */ jsxRuntime.jsx(
2028
+ FolderPanel,
2029
+ {
2030
+ tree,
2031
+ loading: foldersLoading,
2032
+ selectedFolderId,
2033
+ isRootOnly,
2034
+ collapsed: sidebarCollapsed,
2035
+ onToggle: () => setSidebarCollapsed((c) => !c),
2036
+ onSelectAll: handleSelectAll,
2037
+ onSelectRootOnly: handleSelectRootOnly,
2038
+ onSelectFolder: handleSelectFolder,
2039
+ onCreate: handleCreateFolder,
2040
+ onRename: handleRenameFolder,
2041
+ onDelete: handleDeleteFolder
2042
+ }
2043
+ ),
2044
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-container", children: [
2045
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-header", children: [
2046
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "nk-title", children: title }),
2047
+ /* @__PURE__ */ jsxRuntime.jsx(SearchBar, { value: (_c = params.search) != null ? _c : "", onChange: handleSearch }),
2048
+ /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "nk-btn nk-btn--primary", onClick: handleNew, children: [
2049
+ "+ ",
2050
+ "\u0421\u043E\u0437\u0434\u0430\u0442\u044C"
2051
+ ] })
2052
+ ] }),
2053
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "var(--nk-danger)", fontSize: 14, marginBottom: 12 }, children: error.message }),
2054
+ totalPages > 0 && !loading && notes.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-toolbar", children: [
2055
+ /* @__PURE__ */ jsxRuntime.jsx(SortBar, { value: (_d = params.sort) != null ? _d : "updatedAt,desc", onChange: handleSortChange }),
2056
+ /* @__PURE__ */ jsxRuntime.jsx(
2057
+ Pagination,
2058
+ {
2059
+ currentPage,
2060
+ totalPages,
2061
+ totalElements,
2062
+ pageSize: (_e = params.size) != null ? _e : pageSize,
2063
+ pageSizeOptions,
2064
+ onPageChange: goToPage,
2065
+ onPageSizeChange: handlePageSizeChange
2066
+ }
2067
+ )
2068
+ ] }),
2069
+ loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-spinner" }) : notes.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nk-empty", children: [
2070
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-empty__icon", children: "\u{1F4DD}" }),
2071
+ params.search ? "\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0432\u0430\u0448\u0435\u043C\u0443 \u0437\u0430\u043F\u0440\u043E\u0441\u0443." : "\u0417\u0430\u043C\u0435\u0442\u043E\u043A \u043F\u043E\u043A\u0430 \u043D\u0435\u0442. \u0421\u043E\u0437\u0434\u0430\u0439\u0442\u0435 \u043F\u0435\u0440\u0432\u0443\u044E!"
2072
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nk-grid", children: notes.map((note) => /* @__PURE__ */ jsxRuntime.jsx(NoteCard, { note, onEdit: handleCardClick, onDelete: setDeleting, onMove: setMoving, onClone: setCloning }, note.id)) })
2073
+ ] })
2074
+ ] }),
2075
+ isEditorOpen && /* @__PURE__ */ jsxRuntime.jsx(
2076
+ NoteEditor,
2077
+ {
2078
+ note: editing != null ? editing : null,
2079
+ loading: editLoading,
2080
+ onSave: handleSave,
2081
+ onClose: () => {
2082
+ setEditing(void 0);
2083
+ setEditLoading(false);
2084
+ }
2085
+ }
2086
+ ),
2087
+ moving && /* @__PURE__ */ jsxRuntime.jsx(
2088
+ FolderPickerDialog,
2089
+ {
2090
+ title: `\u041F\u0435\u0440\u0435\u043C\u0435\u0441\u0442\u0438\u0442\u044C \xAB${moving.title || "\u0411\u0435\u0437 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430"}\xBB`,
2091
+ tree,
2092
+ currentFolderId: moving.folderId,
2093
+ onConfirm: handleMove,
2094
+ onCancel: () => setMoving(null),
2095
+ loading: moveLoading
2096
+ }
2097
+ ),
2098
+ cloning && /* @__PURE__ */ jsxRuntime.jsx(
2099
+ FolderPickerDialog,
2100
+ {
2101
+ title: `\u041A\u043B\u043E\u043D\u0438\u0440\u043E\u0432\u0430\u0442\u044C \xAB${cloning.title || "\u0411\u0435\u0437 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430"}\xBB`,
2102
+ tree,
2103
+ currentFolderId: cloning.folderId,
2104
+ onConfirm: handleClone,
2105
+ onCancel: () => setCloning(null),
2106
+ loading: cloneLoading
2107
+ }
2108
+ ),
2109
+ deleting && /* @__PURE__ */ jsxRuntime.jsx(
2110
+ ConfirmDialog,
2111
+ {
2112
+ message: `\u0423\u0434\u0430\u043B\u0438\u0442\u044C \xAB${deleting.title || "\u0411\u0435\u0437 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430"}\xBB? \u042D\u0442\u043E \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043D\u0435\u043B\u044C\u0437\u044F \u043E\u0442\u043C\u0435\u043D\u0438\u0442\u044C.`,
2113
+ onConfirm: handleDelete,
2114
+ onCancel: () => setDeleting(null),
2115
+ loading: deleteLoading
2116
+ }
2117
+ )
2118
+ ] });
2119
+ }
2120
+
2121
+ exports.ConfirmDialog = ConfirmDialog;
2122
+ exports.FolderPanel = FolderPanel;
2123
+ exports.FolderPickerDialog = FolderPickerDialog;
2124
+ exports.NoteCard = NoteCard;
2125
+ exports.NoteEditor = NoteEditor;
2126
+ exports.NotesApi = NotesApi;
2127
+ exports.NotesKitError = NotesKitError;
2128
+ exports.NotesKitProvider = NotesKitProvider;
2129
+ exports.NotesWidget = NotesWidget;
2130
+ exports.Pagination = Pagination;
2131
+ exports.SearchBar = SearchBar;
2132
+ exports.SortBar = SortBar;
2133
+ exports.useFolders = useFolders;
2134
+ exports.useNotes = useNotes;
2135
+ exports.useNotesKitContext = useNotesKitContext;
2136
+ //# sourceMappingURL=index.cjs.js.map