@humandialog/forms.svelte 0.5.20 → 0.5.22
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/components/Fab.svelte +0 -1
- package/components/combo/combo.svelte +42 -13
- package/components/combo/combo.svelte.d.ts +1 -0
- package/components/contextmenu.svelte +0 -1
- package/components/document/rich.edit.svelte +0 -1
- package/components/kanban/Kanban.d.ts +2 -0
- package/components/kanban/Kanban.js +24 -0
- package/components/kanban/internal/kanban.card.svelte +42 -26
- package/components/kanban/internal/kanban.column.svelte +46 -10
- package/components/kanban/internal/kanban.column.svelte.d.ts +2 -0
- package/components/kanban/internal/kanban.inserter.svelte +44 -6
- package/components/kanban/internal/kanban.props.svelte +2 -0
- package/components/kanban/kanban.combo.svelte +2 -0
- package/components/kanban/kanban.combo.svelte.d.ts +1 -0
- package/components/kanban/kanban.svelte +11 -4
- package/components/kanban/kanban.title.svelte +2 -0
- package/components/kanban/kanban.title.svelte.d.ts +1 -0
- package/components/list/List.d.ts +1 -0
- package/components/list/List.js +1 -0
- package/components/list/internal/list.element.props.svelte +1 -0
- package/components/list/internal/list.element.svelte +1 -0
- package/components/list/internal/list.inserter.svelte +55 -17
- package/components/list/list.combo.svelte +2 -0
- package/components/list/list.combo.svelte.d.ts +1 -0
- package/components/list/list.svelte +7 -4
- package/components/sidebar/sidebar.item.svelte +76 -22
- package/components/sidebar/sidebar.item.svelte.d.ts +3 -0
- package/components/sidebar/sidebar.list.svelte +23 -3
- package/components/sidebar/sidebar.list.svelte.d.ts +3 -0
- package/components/table/table.svelte +0 -1
- package/package.json +1 -1
- package/utils.js +21 -7
package/components/Fab.svelte
CHANGED
|
@@ -26,6 +26,7 @@ export let inContext = "sel";
|
|
|
26
26
|
export let cached = false;
|
|
27
27
|
export let filtered = false;
|
|
28
28
|
export let pushChangesImmediately = true;
|
|
29
|
+
export let hasNone = isAssociation;
|
|
29
30
|
let is_compact = getContext("rIs-table-component") || compact;
|
|
30
31
|
if (!definition) {
|
|
31
32
|
definition = new rCombo_definition();
|
|
@@ -265,14 +266,18 @@ async function on_choose(itm) {
|
|
|
265
266
|
if (onSelect) {
|
|
266
267
|
if (itm == new_item_option)
|
|
267
268
|
await onNewItemCreated(itm.Key, itm.Name);
|
|
268
|
-
else
|
|
269
|
-
|
|
269
|
+
else {
|
|
270
|
+
if (itm)
|
|
271
|
+
await onSelect(item, itm.Key, itm.Name);
|
|
272
|
+
else
|
|
273
|
+
await onSelect(item, null, null);
|
|
274
|
+
}
|
|
270
275
|
tick_request_internal = tick_request_internal + 1;
|
|
271
276
|
} else {
|
|
272
277
|
if (isAssociation) {
|
|
273
278
|
if (choiceCallback) {
|
|
274
279
|
let body = {
|
|
275
|
-
choice: itm.Key
|
|
280
|
+
choice: itm ? itm.Key : null
|
|
276
281
|
};
|
|
277
282
|
let path;
|
|
278
283
|
if (item.$ref)
|
|
@@ -297,15 +302,19 @@ async function on_choose(itm) {
|
|
|
297
302
|
let result = await reef.post(
|
|
298
303
|
path,
|
|
299
304
|
{
|
|
300
|
-
[a]: itm.Key
|
|
305
|
+
[a]: itm ? itm.Key : null
|
|
301
306
|
}
|
|
302
307
|
);
|
|
303
308
|
if (result) {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
+
if (itm) {
|
|
310
|
+
let name = definition.element_name ?? "$display";
|
|
311
|
+
item[a] = {
|
|
312
|
+
$ref: itm.Key,
|
|
313
|
+
[name]: itm.Name
|
|
314
|
+
};
|
|
315
|
+
} else {
|
|
316
|
+
item[a] = null;
|
|
317
|
+
}
|
|
309
318
|
tick_request_internal = tick_request_internal + 1;
|
|
310
319
|
}
|
|
311
320
|
}
|
|
@@ -319,14 +328,14 @@ async function on_choose(itm) {
|
|
|
319
328
|
let fields = calc_path_fields_param();
|
|
320
329
|
if (fields)
|
|
321
330
|
path += fields;
|
|
322
|
-
let value = itm.Key ?? itm.Name;
|
|
331
|
+
let value = itm ? itm.Key ?? itm.Name : null;
|
|
323
332
|
let result = await reef.post(path, { choice: value });
|
|
324
333
|
if (result) {
|
|
325
334
|
item[a] = result;
|
|
326
335
|
tick_request_internal = tick_request_internal + 1;
|
|
327
336
|
}
|
|
328
337
|
} else {
|
|
329
|
-
item[a] = itm.Key ?? itm.Name;
|
|
338
|
+
item[a] = itm ? itm.Key ?? itm.Name : null;
|
|
330
339
|
tick_request_internal = tick_request_internal + 1;
|
|
331
340
|
if (item && a && typename) {
|
|
332
341
|
informModification(item, a, typename);
|
|
@@ -336,8 +345,12 @@ async function on_choose(itm) {
|
|
|
336
345
|
}
|
|
337
346
|
}
|
|
338
347
|
}
|
|
339
|
-
if (!!changed)
|
|
340
|
-
|
|
348
|
+
if (!!changed) {
|
|
349
|
+
if (itm)
|
|
350
|
+
changed(itm.Key, itm.Name);
|
|
351
|
+
else
|
|
352
|
+
changed(null, null);
|
|
353
|
+
}
|
|
341
354
|
}
|
|
342
355
|
function on_keydown(e) {
|
|
343
356
|
switch (e.key) {
|
|
@@ -588,6 +601,22 @@ function on_focus_out(e) {
|
|
|
588
601
|
<ul class="py-1">
|
|
589
602
|
|
|
590
603
|
{#if definition.source && definition.source.length}
|
|
604
|
+
{#if hasNone}
|
|
605
|
+
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
606
|
+
<li class="rounded p-2 flex flex-row items-center {font_size}"
|
|
607
|
+
class:bg-stone-100={highlighted_option == null}
|
|
608
|
+
class:dark:bg-stone-700={highlighted_option == null}
|
|
609
|
+
class:dark:hover:bg-stone-700={highlighted_option == null}
|
|
610
|
+
on:mousemove={() => on_mouse_move(null)}
|
|
611
|
+
on:click|preventDefault|stopPropagation={async () => await on_choose(null)}
|
|
612
|
+
tabindex="-1">
|
|
613
|
+
|
|
614
|
+
<div class="ml-2">
|
|
615
|
+
<none>
|
|
616
|
+
</div>
|
|
617
|
+
</li>
|
|
618
|
+
{/if}
|
|
619
|
+
|
|
591
620
|
{@const _filtered_source = filtered_source ? filtered_source : definition.source}
|
|
592
621
|
{#if _filtered_source.length > 0}
|
|
593
622
|
{#each _filtered_source as item (item.Key)}
|
|
@@ -22,6 +22,7 @@ declare const __propDef: {
|
|
|
22
22
|
cached?: boolean | undefined;
|
|
23
23
|
filtered?: boolean | undefined;
|
|
24
24
|
pushChangesImmediately?: boolean | undefined;
|
|
25
|
+
hasNone?: boolean | undefined;
|
|
25
26
|
show?: ((event: any, hide_callback: any) => void) | undefined;
|
|
26
27
|
hide?: (() => void) | undefined;
|
|
27
28
|
};
|
|
@@ -28,7 +28,6 @@ afterUpdate(() => {
|
|
|
28
28
|
const sel = window.getSelection();
|
|
29
29
|
if (sel && sel.rangeCount > 0 && sel.focusNode && sel.focusNode.nodeType == sel.focusNode.TEXT_NODE) {
|
|
30
30
|
container_rect.height -= 300;
|
|
31
|
-
console.log("shirnked: ", container_rect);
|
|
32
31
|
}
|
|
33
32
|
}
|
|
34
33
|
let xShifted = false;
|
|
@@ -963,7 +963,6 @@ function on_focus() {
|
|
|
963
963
|
}
|
|
964
964
|
function on_blur() {
|
|
965
965
|
let active_range = Selection_helper.get_selection(editable_div);
|
|
966
|
-
console.log("rich.edit: on_blur", active_range?.begin?.absolute_index);
|
|
967
966
|
storedSelection = null;
|
|
968
967
|
if (onBlur) {
|
|
969
968
|
onBlur();
|
|
@@ -18,6 +18,7 @@ export declare class rKanban_definition {
|
|
|
18
18
|
titleReadOnly: boolean;
|
|
19
19
|
titleHref: string | undefined;
|
|
20
20
|
titleHrefFunc: Function | undefined;
|
|
21
|
+
titleHasAttachment: Function | undefined;
|
|
21
22
|
summaryAttrib: string;
|
|
22
23
|
summaryOnChange: Function | undefined;
|
|
23
24
|
summaryReadOnly: boolean;
|
|
@@ -39,6 +40,7 @@ export declare class rKanban_definition {
|
|
|
39
40
|
getCardOperations: Function | undefined;
|
|
40
41
|
private items;
|
|
41
42
|
getItems(): object[];
|
|
43
|
+
visibleColumnsNo(): number;
|
|
42
44
|
clear(): void;
|
|
43
45
|
}
|
|
44
46
|
export declare const KanbanColumnTop = -1;
|
|
@@ -17,6 +17,7 @@ export class rKanban_definition {
|
|
|
17
17
|
titleReadOnly = false;
|
|
18
18
|
titleHref = undefined;
|
|
19
19
|
titleHrefFunc = undefined;
|
|
20
|
+
titleHasAttachment = undefined;
|
|
20
21
|
summaryAttrib = '';
|
|
21
22
|
summaryOnChange = undefined;
|
|
22
23
|
summaryReadOnly = false;
|
|
@@ -50,6 +51,29 @@ export class rKanban_definition {
|
|
|
50
51
|
}
|
|
51
52
|
return this.items;
|
|
52
53
|
}
|
|
54
|
+
visibleColumnsNo() {
|
|
55
|
+
// has <Other> column
|
|
56
|
+
if (this.columns.find((c) => c.state < 0)) {
|
|
57
|
+
const allItems = this.getItems();
|
|
58
|
+
const isExplicitState = (e) => {
|
|
59
|
+
const elementState = e[this.stateAttrib];
|
|
60
|
+
const colsNo = this.columns.length;
|
|
61
|
+
for (let i = 0; i < colsNo; i++) {
|
|
62
|
+
const def = this.columns[i];
|
|
63
|
+
if ((def.state >= 0) && (def.state == elementState))
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
};
|
|
68
|
+
const unknownStateItems = allItems.filter(e => !isExplicitState(e));
|
|
69
|
+
if (unknownStateItems && (unknownStateItems.length > 0))
|
|
70
|
+
return this.columns.length;
|
|
71
|
+
else
|
|
72
|
+
return this.columns.length - 1;
|
|
73
|
+
}
|
|
74
|
+
else
|
|
75
|
+
return this.columns.length;
|
|
76
|
+
}
|
|
53
77
|
clear() {
|
|
54
78
|
this.columns = [];
|
|
55
79
|
this.titleAttrib = '';
|
|
@@ -12,8 +12,7 @@ import {
|
|
|
12
12
|
pushChanges,
|
|
13
13
|
startEditing
|
|
14
14
|
} from "../../..";
|
|
15
|
-
import {
|
|
16
|
-
import MoveOperations from "./kanban.move.menu.svelte";
|
|
15
|
+
import { FaRegFileAlt } from "svelte-icons/fa";
|
|
17
16
|
import Properties from "./kanban.props.svelte";
|
|
18
17
|
import { KanbanCardTop, KanbanCardMiddle, KanbanCardBottom } from "../Kanban";
|
|
19
18
|
export let item;
|
|
@@ -148,6 +147,28 @@ function getHRef() {
|
|
|
148
147
|
else
|
|
149
148
|
return "";
|
|
150
149
|
}
|
|
150
|
+
function performOpen(e) {
|
|
151
|
+
e.stopPropagation();
|
|
152
|
+
if (isLinkLike)
|
|
153
|
+
followDefinedHRef();
|
|
154
|
+
else
|
|
155
|
+
definition.onOpen(item);
|
|
156
|
+
}
|
|
157
|
+
function conditionalClick(node, { condition, callback }) {
|
|
158
|
+
if (condition) {
|
|
159
|
+
node.addEventListener("click", callback);
|
|
160
|
+
return {
|
|
161
|
+
destroy() {
|
|
162
|
+
node.removeEventListener("click", callback);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function showAttachementIcon() {
|
|
168
|
+
if (!definition.titleHasAttachment)
|
|
169
|
+
return false;
|
|
170
|
+
return definition.titleHasAttachment(item);
|
|
171
|
+
}
|
|
151
172
|
</script>
|
|
152
173
|
|
|
153
174
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
@@ -183,43 +204,38 @@ function getHRef() {
|
|
|
183
204
|
|
|
184
205
|
|
|
185
206
|
{#if isCardActive}
|
|
186
|
-
{
|
|
207
|
+
{@const hasOpen = !!definition.onOpen}
|
|
208
|
+
{@const canOpen = isLinkLike || hasOpen}
|
|
209
|
+
{@const openableClass = canOpen ? "sm:hover:cursor-pointer underline" : ""}
|
|
210
|
+
{@const showIcon = showAttachementIcon()}
|
|
187
211
|
<h3 class=" text-lg font-semibold min-h-[1.75rem]
|
|
188
212
|
sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
|
|
189
213
|
whitespace-nowrap overflow-clip truncate w-full sm:flex-none
|
|
190
|
-
relative
|
|
191
|
-
sm:hover:cursor-pointer underline"
|
|
192
|
-
on:click|stopPropagation={followDefinedHRef}
|
|
214
|
+
relative {openableClass}"
|
|
193
215
|
use:editable={{
|
|
194
216
|
action: (text) => onTitleChanged(text),
|
|
195
217
|
active: false,
|
|
196
218
|
readonly: definition.titleReadOnly,
|
|
197
|
-
onFinish: (d) => {titleElement.blur()}
|
|
219
|
+
onFinish: (d) => {titleElement.blur()},
|
|
220
|
+
onSoftEnter: async (text) => { onTitleChanged(text); await editProperty('Summary') }
|
|
221
|
+
}}
|
|
222
|
+
use:conditionalClick={{
|
|
223
|
+
condition: canOpen,
|
|
224
|
+
callback: performOpen}}
|
|
198
225
|
bind:this={titleElement}>
|
|
199
226
|
{item[definition.titleAttrib]}
|
|
200
|
-
</h3>
|
|
201
|
-
{:else}
|
|
202
|
-
<h3 class=" text-lg font-semibold min-h-[1.75rem]
|
|
203
|
-
sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
|
|
204
|
-
whitespace-nowrap overflow-clip truncate w-full sm:flex-none
|
|
205
|
-
relative"
|
|
206
|
-
use:editable={{
|
|
207
|
-
action: (text) => onTitleChanged(text),
|
|
208
|
-
active: true,
|
|
209
|
-
readonly: definition.titleReadOnly,
|
|
210
|
-
onFinish: (d) => {titleElement.blur()}}}
|
|
211
|
-
bind:this={titleElement}>
|
|
212
|
-
{item[definition.titleAttrib]}
|
|
213
227
|
|
|
214
|
-
{#if
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
</button>
|
|
228
|
+
{#if showIcon}
|
|
229
|
+
<span id="attachement" class="absolute top-1 right-0 w-5 h-5 sm:w-3 sm:h-3">
|
|
230
|
+
<FaRegFileAlt/>
|
|
231
|
+
</span>
|
|
219
232
|
{/if}
|
|
220
233
|
</h3>
|
|
221
|
-
|
|
234
|
+
|
|
235
|
+
<!--Tooltip type='light' triggeredBy="#attachement">Has attachement</Tooltip-->
|
|
222
236
|
|
|
237
|
+
|
|
238
|
+
|
|
223
239
|
{:else}
|
|
224
240
|
<h3 class=" text-lg font-semibold min-h-[1.75rem]
|
|
225
241
|
sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
|
|
@@ -9,6 +9,8 @@ export let currentColumnIdx;
|
|
|
9
9
|
export let onInsert;
|
|
10
10
|
let column_element;
|
|
11
11
|
export function getHeight() {
|
|
12
|
+
if (!column_element)
|
|
13
|
+
return 0;
|
|
12
14
|
return column_element.getBoundingClientRect().height;
|
|
13
15
|
}
|
|
14
16
|
let titleElement;
|
|
@@ -20,6 +22,8 @@ export const SET_RIGHT = 1;
|
|
|
20
22
|
export const CLEAR_LEFT = 2;
|
|
21
23
|
export const CLEAR_RIGHT = 3;
|
|
22
24
|
export function setBorder(what_to_do) {
|
|
25
|
+
if (!column_element)
|
|
26
|
+
return;
|
|
23
27
|
switch (what_to_do) {
|
|
24
28
|
case SET_LEFT:
|
|
25
29
|
column_element.classList.add("border-l");
|
|
@@ -52,8 +56,31 @@ $:
|
|
|
52
56
|
force_rerender($data_tick_store, $contextItemsStore);
|
|
53
57
|
export function reload() {
|
|
54
58
|
let allItems = definition.getItems();
|
|
55
|
-
if (definition.stateAttrib)
|
|
56
|
-
|
|
59
|
+
if (definition.stateAttrib) {
|
|
60
|
+
if (columnDef.state < 0) {
|
|
61
|
+
const isExplicitState = (e) => {
|
|
62
|
+
const elementState = e[definition.stateAttrib];
|
|
63
|
+
const colsNo = definition.columns.length;
|
|
64
|
+
for (let i = 0; i < colsNo; i++) {
|
|
65
|
+
const def = definition.columns[i];
|
|
66
|
+
if (def.state >= 0 && def.state == elementState)
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
};
|
|
71
|
+
column_items = allItems.filter((e) => !isExplicitState(e));
|
|
72
|
+
} else
|
|
73
|
+
column_items = allItems.filter((e) => e[definition.stateAttrib] == columnDef.state);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export function isVisible() {
|
|
77
|
+
if (columnDef.state < 0) {
|
|
78
|
+
if (column_items && column_items.length > 0)
|
|
79
|
+
return true;
|
|
80
|
+
else
|
|
81
|
+
return false;
|
|
82
|
+
} else
|
|
83
|
+
return true;
|
|
57
84
|
}
|
|
58
85
|
function setup_data(...args) {
|
|
59
86
|
reload();
|
|
@@ -111,6 +138,8 @@ export async function add(after = KanbanColumnTop) {
|
|
|
111
138
|
if (!inserter)
|
|
112
139
|
return;
|
|
113
140
|
inserter.run(async (detail) => {
|
|
141
|
+
if (detail.softEnter)
|
|
142
|
+
return;
|
|
114
143
|
showInserterAfterId = None;
|
|
115
144
|
if (detail.cancel)
|
|
116
145
|
activateAfterDomUpdate = lastActivatedElement;
|
|
@@ -175,11 +204,14 @@ function onResizeWindow() {
|
|
|
175
204
|
styleWidth = getWidthStyle();
|
|
176
205
|
}
|
|
177
206
|
function getWidthStyle() {
|
|
178
|
-
const
|
|
179
|
-
const
|
|
180
|
-
const
|
|
207
|
+
const container = document.getElementById("__hd_svelte_main_content_container");
|
|
208
|
+
const containerRect = container?.getBoundingClientRect();
|
|
209
|
+
const assumed_space = containerRect.width;
|
|
210
|
+
const columns_no = definition.visibleColumnsNo();
|
|
211
|
+
const default_column_width = Math.floor(assumed_space / columns_no);
|
|
212
|
+
const column_width = Math.min(columnDef.width ? columnDef.width : default_column_width, 640);
|
|
181
213
|
if (window.innerWidth >= 640)
|
|
182
|
-
return `width: ${column_width}px; min-width:
|
|
214
|
+
return `width: ${column_width}px; min-width: 200px; max-width: ${column_width}px;`;
|
|
183
215
|
else
|
|
184
216
|
return "width: 92%;";
|
|
185
217
|
}
|
|
@@ -187,6 +219,8 @@ function getWidthStyle() {
|
|
|
187
219
|
|
|
188
220
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
189
221
|
|
|
222
|
+
{#if (columnDef.state >=0) || ((column_items && column_items.length > 0))}
|
|
223
|
+
|
|
190
224
|
<section class=" snap-center
|
|
191
225
|
sm:snap-align-none
|
|
192
226
|
flex-none sm:flex-1
|
|
@@ -194,6 +228,8 @@ function getWidthStyle() {
|
|
|
194
228
|
min-h-[calc(100vh-5rem)]
|
|
195
229
|
rounded-md border border-transparent
|
|
196
230
|
{selected_class} {focused_class}"
|
|
231
|
+
|
|
232
|
+
|
|
197
233
|
style={styleWidth}
|
|
198
234
|
use:selectable={columnDef}
|
|
199
235
|
on:click={activate}>
|
|
@@ -221,7 +257,7 @@ function getWidthStyle() {
|
|
|
221
257
|
</header>
|
|
222
258
|
<ul class="w-full border-stone-700 pb-20" bind:this={column_element}>
|
|
223
259
|
{#if showInserterAfterId === KanbanColumnTop}
|
|
224
|
-
<Inserter onInsert={async (
|
|
260
|
+
<Inserter onInsert={async (title, summary) => {await onInsert(currentColumnIdx, title, summary, KanbanColumnTop)}}
|
|
225
261
|
bind:this={inserter} />
|
|
226
262
|
{/if}
|
|
227
263
|
|
|
@@ -243,17 +279,17 @@ function getWidthStyle() {
|
|
|
243
279
|
</Card>
|
|
244
280
|
|
|
245
281
|
{#if showInserterAfterId == element.Id}
|
|
246
|
-
<Inserter onInsert={async (
|
|
282
|
+
<Inserter onInsert={async (title, summary) => {await onInsert(currentColumnIdx, title, summary, showInserterAfterId)}}
|
|
247
283
|
bind:this={inserter} />
|
|
248
284
|
{/if}
|
|
249
285
|
{/each}
|
|
250
286
|
{/if}
|
|
251
287
|
|
|
252
288
|
{#if showInserterAfterId === KanbanColumnBottom}
|
|
253
|
-
<Inserter onInsert={async (
|
|
289
|
+
<Inserter onInsert={async (title, summary) => {await onInsert(currentColumnIdx, title, summary, KanbanColumnBottom)}}
|
|
254
290
|
bind:this={inserter} />
|
|
255
291
|
{/if}
|
|
256
292
|
|
|
257
293
|
</ul>
|
|
258
294
|
</section>
|
|
259
|
-
|
|
295
|
+
{/if}
|
|
@@ -11,6 +11,7 @@ declare const __propDef: {
|
|
|
11
11
|
CLEAR_RIGHT?: 3 | undefined;
|
|
12
12
|
setBorder?: ((what_to_do: number) => void) | undefined;
|
|
13
13
|
reload?: (() => void) | undefined;
|
|
14
|
+
isVisible?: (() => boolean) | undefined;
|
|
14
15
|
findCardByItem?: ((item: object) => any) | undefined;
|
|
15
16
|
activateByItemId?: ((id: number) => void) | undefined;
|
|
16
17
|
add?: ((after?: object | number) => Promise<void>) | undefined;
|
|
@@ -43,6 +44,7 @@ export default class Kanban extends SvelteComponentTyped<KanbanProps, KanbanEven
|
|
|
43
44
|
get CLEAR_RIGHT(): 3;
|
|
44
45
|
get setBorder(): (what_to_do: number) => void;
|
|
45
46
|
get reload(): () => void;
|
|
47
|
+
get isVisible(): () => boolean;
|
|
46
48
|
get findCardByItem(): (item: object) => any;
|
|
47
49
|
get activateByItemId(): (id: number) => void;
|
|
48
50
|
get add(): (after?: number | object) => Promise<void>;
|
|
@@ -1,12 +1,29 @@
|
|
|
1
|
-
<script>import {
|
|
1
|
+
<script>import { tick } from "svelte";
|
|
2
|
+
import {
|
|
2
3
|
startEditing,
|
|
3
4
|
editable
|
|
4
5
|
} from "../../..";
|
|
5
6
|
export let onInsert;
|
|
7
|
+
let onClose;
|
|
6
8
|
export function run(onclose) {
|
|
7
|
-
|
|
9
|
+
onClose = onclose;
|
|
10
|
+
startEditing(titleElement, onclose);
|
|
11
|
+
}
|
|
12
|
+
let titleElement;
|
|
13
|
+
let title = "";
|
|
14
|
+
let summary = "";
|
|
15
|
+
let editSummary = false;
|
|
16
|
+
let summaryElement;
|
|
17
|
+
async function softEnter(t) {
|
|
18
|
+
title = t;
|
|
19
|
+
editSummary = true;
|
|
20
|
+
await tick();
|
|
21
|
+
startEditing(summaryElement, onClose);
|
|
22
|
+
}
|
|
23
|
+
async function onSummaryChanged(text) {
|
|
24
|
+
summary = text;
|
|
25
|
+
await onInsert(title, summary);
|
|
8
26
|
}
|
|
9
|
-
let insertion_paragraph;
|
|
10
27
|
</script>
|
|
11
28
|
|
|
12
29
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
@@ -17,8 +34,29 @@ let insertion_paragraph;
|
|
|
17
34
|
<h3 class=" text-lg font-semibold min-h-[1.75rem]
|
|
18
35
|
sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
|
|
19
36
|
whitespace-nowrap overflow-clip w-full sm:flex-none "
|
|
20
|
-
use:editable={
|
|
21
|
-
|
|
22
|
-
|
|
37
|
+
use:editable={{
|
|
38
|
+
action: (text) => onInsert(text, ''),
|
|
39
|
+
active: false,
|
|
40
|
+
onSoftEnter: softEnter
|
|
41
|
+
}}
|
|
42
|
+
bind:this={titleElement}>
|
|
23
43
|
</h3>
|
|
44
|
+
|
|
45
|
+
{#if editSummary}
|
|
46
|
+
<p class=" sm:text-xs sm:min-h-[1rem]
|
|
47
|
+
text-base min-h-[1.5rem]
|
|
48
|
+
text-stone-400
|
|
49
|
+
max-h-[75px] sm:max-h-[64px]
|
|
50
|
+
overflow-hidden"
|
|
51
|
+
use:editable={{
|
|
52
|
+
action: (text) => onSummaryChanged(text),
|
|
53
|
+
active: false,
|
|
54
|
+
onFinish: (d) => {editSummary = false}}}
|
|
55
|
+
bind:this={summaryElement}>
|
|
56
|
+
{summary}
|
|
57
|
+
</p>
|
|
58
|
+
{/if}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
24
62
|
</li>
|
|
@@ -107,9 +107,11 @@ async function editTags(field, propIdx) {
|
|
|
107
107
|
a={prop.a}
|
|
108
108
|
onSelect={prop.onSelect}
|
|
109
109
|
isAssociation={prop.association}
|
|
110
|
+
hasNone={prop.hasNone}
|
|
110
111
|
icon={false}
|
|
111
112
|
definition={prop.combo_definition}
|
|
112
113
|
s="xs"
|
|
114
|
+
changed={(k,n) => { /*fake assignment for component rer-ender*/ item[prop.a] = item[prop.a]; }}
|
|
113
115
|
bind:this={propElements[idx]}/>
|
|
114
116
|
{:else if prop.type == rList_property_type.Static}
|
|
115
117
|
<p
|
|
@@ -6,6 +6,7 @@ export let name = "";
|
|
|
6
6
|
export let a = "";
|
|
7
7
|
export let onSelect = void 0;
|
|
8
8
|
export let association = false;
|
|
9
|
+
export let hasNone = association;
|
|
9
10
|
export let top = false;
|
|
10
11
|
export let middle = true;
|
|
11
12
|
export let bottom = false;
|
|
@@ -23,6 +24,7 @@ if (!a && name) {
|
|
|
23
24
|
}
|
|
24
25
|
combo_property.onSelect = onSelect;
|
|
25
26
|
combo_property.association = association;
|
|
27
|
+
combo_property.hasNone = hasNone;
|
|
26
28
|
if (top)
|
|
27
29
|
combo_property.position = KanbanCardTop;
|
|
28
30
|
else if (bottom)
|
|
@@ -125,7 +125,12 @@ export async function reload(data, selectElement = KEEP_SELECTION) {
|
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
export function getColumnIdx(item) {
|
|
128
|
-
|
|
128
|
+
let idx = definition.columns.findIndex((c2) => c2.state == item[definition.stateAttrib]);
|
|
129
|
+
if (idx >= 0)
|
|
130
|
+
return idx;
|
|
131
|
+
else {
|
|
132
|
+
return definition.columns.findIndex((c2) => c2.state < 0);
|
|
133
|
+
}
|
|
129
134
|
}
|
|
130
135
|
export function edit(item, field) {
|
|
131
136
|
const columnIdx = getColumnIdx(item);
|
|
@@ -299,7 +304,7 @@ export function replace(item, toColumnIdx, afterElement) {
|
|
|
299
304
|
return;
|
|
300
305
|
}
|
|
301
306
|
}
|
|
302
|
-
async function onInsert(columnIdx, title2, afterId) {
|
|
307
|
+
async function onInsert(columnIdx, title2, summary, afterId) {
|
|
303
308
|
const columnState = definition.columns[columnIdx].state;
|
|
304
309
|
const oa = definition.orderAttrib;
|
|
305
310
|
const sa = definition.stateAttrib;
|
|
@@ -308,6 +313,7 @@ async function onInsert(columnIdx, title2, afterId) {
|
|
|
308
313
|
const columnBottom = allItems.findLast((e) => e[sa] == columnState);
|
|
309
314
|
let newElement = {
|
|
310
315
|
[definition.titleAttrib]: title2,
|
|
316
|
+
[definition.summaryAttrib]: summary,
|
|
311
317
|
[sa]: columnState
|
|
312
318
|
};
|
|
313
319
|
if (afterId == KanbanColumnTop) {
|
|
@@ -427,9 +433,10 @@ export function add(item, columnIdx = -1) {
|
|
|
427
433
|
<!--hr class="hidden sm:block w-full"-->
|
|
428
434
|
{/if}
|
|
429
435
|
|
|
430
|
-
<section
|
|
436
|
+
<section id="__hd_svelte_kanban_columns_container"
|
|
437
|
+
class="h-full mt-5 flex flex-row no-wrap
|
|
431
438
|
overflow-x-auto snap-x snap-mandatory sm:snap-none
|
|
432
|
-
{user_class}">
|
|
439
|
+
{user_class}"> <!--sm:justify-center -->
|
|
433
440
|
{#each definition.columns as column, idx (column.id)}
|
|
434
441
|
<Column currentColumnIdx={idx}
|
|
435
442
|
{onInsert}
|
|
@@ -4,11 +4,13 @@ export let onChange = void 0;
|
|
|
4
4
|
export let readOnly = false;
|
|
5
5
|
export let href = void 0;
|
|
6
6
|
export let hrefFunc = void 0;
|
|
7
|
+
export let hasAttachment = void 0;
|
|
7
8
|
let definition = getContext("rKanban-definition");
|
|
8
9
|
definition.titleAttrib = a;
|
|
9
10
|
definition.titleOnChange = onChange;
|
|
10
11
|
definition.titleReadOnly = readOnly;
|
|
11
12
|
definition.titleHref = href;
|
|
12
13
|
definition.titleHrefFunc = hrefFunc;
|
|
14
|
+
definition.titleHasAttachment = hasAttachment;
|
|
13
15
|
</script>
|
|
14
16
|
|
|
@@ -19,6 +19,7 @@ export declare class rList_property_combo extends rList_property {
|
|
|
19
19
|
constructor();
|
|
20
20
|
association: boolean;
|
|
21
21
|
combo_definition: rCombo_definition;
|
|
22
|
+
hasNone: boolean;
|
|
22
23
|
}
|
|
23
24
|
export declare class rList_property_tags extends rList_property {
|
|
24
25
|
constructor();
|
package/components/list/List.js
CHANGED
|
@@ -1,27 +1,65 @@
|
|
|
1
|
-
<script>import {
|
|
1
|
+
<script>import { tick } from "svelte";
|
|
2
|
+
import { editable, startEditing } from "../../../utils";
|
|
2
3
|
import Icon from "../../icon.svelte";
|
|
3
4
|
import { FaPlus } from "svelte-icons/fa";
|
|
4
5
|
export let onInsert;
|
|
5
6
|
export let icon = false;
|
|
7
|
+
let onClose;
|
|
6
8
|
export function run(onclose) {
|
|
7
|
-
|
|
9
|
+
onClose = onclose;
|
|
10
|
+
startEditing(titleElement, onclose);
|
|
11
|
+
}
|
|
12
|
+
let titleElement;
|
|
13
|
+
let summaryElement;
|
|
14
|
+
let title = "";
|
|
15
|
+
let summary = "";
|
|
16
|
+
let editSummary = false;
|
|
17
|
+
async function softEnter(text) {
|
|
18
|
+
title = text;
|
|
19
|
+
editSummary = true;
|
|
20
|
+
await tick();
|
|
21
|
+
startEditing(summaryElement, onClose);
|
|
22
|
+
}
|
|
23
|
+
async function onSummaryChanged(text) {
|
|
24
|
+
summary = text;
|
|
25
|
+
await onInsert(title, summary);
|
|
8
26
|
}
|
|
9
|
-
let insertion_paragraph;
|
|
10
27
|
</script>
|
|
11
28
|
|
|
12
|
-
<section class="mt-3
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
<section class="mt-3 my-0 w-full text-lg sm:text-sm text-stone-700 dark:text-stone-400 cursor-default rounded-md border border-transparent bg-stone-200 dark:bg-stone-700">
|
|
30
|
+
<div class="flex flex-row">
|
|
31
|
+
{#if icon}
|
|
32
|
+
<!--Icon size={3}
|
|
33
|
+
component={FaPlus}
|
|
34
|
+
class="mt-1.5 ml-2 "/-->
|
|
35
|
+
<div class="h-5 w-5 sm:h-4 sm:w-4 mt-2 sm:mt-1.5 ml-2"></div>
|
|
36
|
+
{/if}
|
|
19
37
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
38
|
+
<p class=" ml-3 py-1
|
|
39
|
+
text-lg font-semibold min-h-[1.75rem]
|
|
40
|
+
sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
|
|
41
|
+
whitespace-nowrap overflow-clip flex-none w-1/2 sm:w-1/3" tabindex="0"
|
|
42
|
+
bind:this={titleElement}
|
|
43
|
+
use:editable={{
|
|
44
|
+
action: (text) => onInsert(text, ''),
|
|
45
|
+
active: false,
|
|
46
|
+
onSoftEnter: softEnter
|
|
47
|
+
}} >
|
|
48
|
+
</p>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
{#if editSummary}
|
|
52
|
+
<p bind:this={summaryElement}
|
|
53
|
+
class=" ml-10 sm:ml-9
|
|
54
|
+
sm:text-xs sm:min-h-[1rem]
|
|
55
|
+
text-base min-h-[1.5rem]
|
|
56
|
+
text-stone-400"
|
|
57
|
+
use:editable={{
|
|
58
|
+
action: onSummaryChanged,
|
|
59
|
+
active: false,
|
|
60
|
+
onFinish: (d) => {editSummary=false}
|
|
61
|
+
}}>
|
|
62
|
+
{summary}
|
|
63
|
+
</p>
|
|
64
|
+
{/if}
|
|
27
65
|
</section>
|
|
@@ -5,6 +5,7 @@ export let name;
|
|
|
5
5
|
export let a = "";
|
|
6
6
|
export let onSelect = void 0;
|
|
7
7
|
export let association = false;
|
|
8
|
+
export let hasNone = association;
|
|
8
9
|
let definition = getContext("rList-definition");
|
|
9
10
|
let combo_property = new rList_property_combo();
|
|
10
11
|
combo_property.name = name;
|
|
@@ -13,6 +14,7 @@ if (!combo_property.a)
|
|
|
13
14
|
combo_property.a = combo_property.name;
|
|
14
15
|
combo_property.onSelect = onSelect;
|
|
15
16
|
combo_property.association = association;
|
|
17
|
+
combo_property.hasNone = hasNone;
|
|
16
18
|
definition.properties.push(combo_property);
|
|
17
19
|
setContext("rCombo-definition", combo_property.combo_definition);
|
|
18
20
|
</script>
|
|
@@ -175,6 +175,8 @@ export async function addRowAfter(after = null) {
|
|
|
175
175
|
if (!inserter)
|
|
176
176
|
return;
|
|
177
177
|
inserter.run(async (detail) => {
|
|
178
|
+
if (detail.softEnter)
|
|
179
|
+
return;
|
|
178
180
|
show_insertion_row_after_element = null;
|
|
179
181
|
if (detail.cancel)
|
|
180
182
|
activate_after_dom_update = last_activated_element;
|
|
@@ -233,9 +235,10 @@ function reorderElements(items2, from = null) {
|
|
|
233
235
|
}
|
|
234
236
|
pushChanges();
|
|
235
237
|
}
|
|
236
|
-
async function insert(title2, after) {
|
|
238
|
+
async function insert(title2, summary, after) {
|
|
237
239
|
let newElement = {
|
|
238
|
-
[definition.title]: title2
|
|
240
|
+
[definition.title]: title2,
|
|
241
|
+
[definition.summary]: summary
|
|
239
242
|
};
|
|
240
243
|
if (after && orderAttrib) {
|
|
241
244
|
const leftElement = after;
|
|
@@ -298,7 +301,7 @@ async function insert(title2, after) {
|
|
|
298
301
|
</List_element>
|
|
299
302
|
|
|
300
303
|
{#if show_insertion_row_after_element == element}
|
|
301
|
-
<Inserter onInsert={async (
|
|
304
|
+
<Inserter onInsert={async (title, summary) => {await insert(title, summary, show_insertion_row_after_element)}}
|
|
302
305
|
icon={definition.inserter_icon}
|
|
303
306
|
bind:this={inserter} />
|
|
304
307
|
{/if}
|
|
@@ -306,7 +309,7 @@ async function insert(title2, after) {
|
|
|
306
309
|
{/if}
|
|
307
310
|
|
|
308
311
|
{#if show_insertion_row_after_element == END_OF_LIST}
|
|
309
|
-
<Inserter onInsert={async (
|
|
312
|
+
<Inserter onInsert={async (title, summary) => {await insert(text, summary, null)}}
|
|
310
313
|
icon={definition.inserter_icon}
|
|
311
314
|
bind:this={inserter} />
|
|
312
315
|
{/if}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
editable as _editable,
|
|
9
9
|
handleSelect,
|
|
10
10
|
activateItem,
|
|
11
|
+
startEditing,
|
|
11
12
|
getActive
|
|
12
13
|
} from "../../utils";
|
|
13
14
|
import { showMenu } from "../menu";
|
|
@@ -18,11 +19,48 @@ export let selectable = void 0;
|
|
|
18
19
|
export let editable = void 0;
|
|
19
20
|
export let operations = void 0;
|
|
20
21
|
export let item = void 0;
|
|
22
|
+
export let summary = void 0;
|
|
21
23
|
let isOnPage = getContext("rIs-page-component");
|
|
24
|
+
let summaryElement = null;
|
|
25
|
+
let summaryPlaceholder = false;
|
|
26
|
+
let summaryEditable = void 0;
|
|
22
27
|
$:
|
|
23
28
|
context_data = $contextItemsStore;
|
|
24
29
|
$:
|
|
25
30
|
isRowActive = calculateIsRowActive($contextItemsStore);
|
|
31
|
+
$:
|
|
32
|
+
summaryText = calculateSummary(summary);
|
|
33
|
+
function calculateSummary(...args) {
|
|
34
|
+
if (!summary) {
|
|
35
|
+
summaryEditable = void 0;
|
|
36
|
+
return "";
|
|
37
|
+
}
|
|
38
|
+
if (summary instanceof Object) {
|
|
39
|
+
summaryEditable = summary.editable;
|
|
40
|
+
if (summary.content)
|
|
41
|
+
return summary.content;
|
|
42
|
+
else
|
|
43
|
+
return "";
|
|
44
|
+
} else {
|
|
45
|
+
summaryEditable = void 0;
|
|
46
|
+
return summary;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export async function editSummary() {
|
|
50
|
+
if (!summaryEditable)
|
|
51
|
+
return;
|
|
52
|
+
if (!!summaryElement)
|
|
53
|
+
startEditing(summaryElement, (d) => {
|
|
54
|
+
summaryPlaceholder = false;
|
|
55
|
+
});
|
|
56
|
+
else {
|
|
57
|
+
summaryPlaceholder = true;
|
|
58
|
+
await tick();
|
|
59
|
+
startEditing(summaryElement, (d) => {
|
|
60
|
+
summaryPlaceholder = false;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
26
64
|
let user_class = $$props.class ?? "";
|
|
27
65
|
let root;
|
|
28
66
|
function calculateIsRowActive(...args) {
|
|
@@ -130,34 +168,50 @@ function activateRow(e) {
|
|
|
130
168
|
class=" border border-transparent rounded-lg
|
|
131
169
|
text-lg sm:text-base font-normal
|
|
132
170
|
text-stone-900 sm:hover:bg-stone-100
|
|
133
|
-
dark:text-white sm:dark:hover:bg-stone-700 {user_class}
|
|
134
|
-
flex flex-row justify-between"
|
|
171
|
+
dark:text-white sm:dark:hover:bg-stone-700 {user_class}"
|
|
135
172
|
class:bg-stone-200={isRowActive}
|
|
136
173
|
class:dark:bg-stone-700={isRowActive}
|
|
137
174
|
class:selected={selected(selectable, context_data)}>
|
|
138
|
-
<
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
175
|
+
<div class="flex flex-row justify-between">
|
|
176
|
+
<a href={href}
|
|
177
|
+
on:click={on_link_clicked}
|
|
178
|
+
class="flex-1 ml-2 mt-3 sm:mt-2 inline-flex items-center group"
|
|
179
|
+
class:mb-3={!summary}
|
|
180
|
+
class:sm:mb-2={!summary}
|
|
181
|
+
>
|
|
182
|
+
{#if icon}
|
|
183
|
+
<Icon size={5} component={icon}/>
|
|
184
|
+
{/if}
|
|
185
|
+
<span class="ml-3 group-hover:underline"
|
|
186
|
+
use:editable_if_needed={editable}>
|
|
187
|
+
<slot/>
|
|
188
|
+
</span>
|
|
189
|
+
</a>
|
|
149
190
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
191
|
+
{#if !isOnPage}
|
|
192
|
+
<section class="flex-0 w-20 sm:w-12 h-10 flex-0 flex flex-row"
|
|
193
|
+
use:selectable_if_needed={selectable}>
|
|
194
|
+
{#if can_show_context_menu(selectable, context_data)}
|
|
195
|
+
<button class="w-6 sm:w-4 h-6 sm:h-4 mt-3 mr-3 sm:mr-2 ml-auto" on:click={on_show_menu}>
|
|
196
|
+
<FaBars/>
|
|
197
|
+
</button>
|
|
198
|
+
{/if}
|
|
199
|
+
</section>
|
|
157
200
|
{/if}
|
|
158
|
-
</
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
{#if summary}
|
|
204
|
+
<p class="text-xs ml-10 mb-2 mr-2
|
|
205
|
+
text-stone-900 dark:text-stone-400
|
|
206
|
+
cursor-default"
|
|
207
|
+
use:selectable_if_needed={selectable}
|
|
208
|
+
use:editable_if_needed={summaryEditable}
|
|
209
|
+
bind:this={summaryElement}>
|
|
210
|
+
{summaryText}
|
|
211
|
+
</p>
|
|
159
212
|
{/if}
|
|
160
|
-
|
|
213
|
+
|
|
214
|
+
</div>
|
|
161
215
|
</li>
|
|
162
216
|
|
|
163
217
|
|
|
@@ -9,6 +9,8 @@ declare const __propDef: {
|
|
|
9
9
|
editable?: any | undefined;
|
|
10
10
|
operations?: any | undefined;
|
|
11
11
|
item?: object | undefined;
|
|
12
|
+
summary?: string | object | undefined;
|
|
13
|
+
editSummary?: (() => Promise<void>) | undefined;
|
|
12
14
|
};
|
|
13
15
|
events: {
|
|
14
16
|
click: MouseEvent;
|
|
@@ -25,5 +27,6 @@ export type SidebarProps = typeof __propDef.props;
|
|
|
25
27
|
export type SidebarEvents = typeof __propDef.events;
|
|
26
28
|
export type SidebarSlots = typeof __propDef.slots;
|
|
27
29
|
export default class Sidebar extends SvelteComponentTyped<SidebarProps, SidebarEvents, SidebarSlots> {
|
|
30
|
+
get editSummary(): () => Promise<void>;
|
|
28
31
|
}
|
|
29
32
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>import Icon from "../icon.svelte";
|
|
2
2
|
import Edit from "../edit.field.svelte";
|
|
3
3
|
import { FaPlus } from "svelte-icons/fa";
|
|
4
|
-
import { getPrev, getNext, swapElements, getLast } from "../../utils";
|
|
4
|
+
import { getPrev, getNext, swapElements, getLast, getFirst, remove, insertAt } from "../../utils";
|
|
5
5
|
import { informModification, pushChanges } from "../../updates";
|
|
6
6
|
import { tick } from "svelte";
|
|
7
7
|
export let objects;
|
|
@@ -28,6 +28,26 @@ export function moveUp(element) {
|
|
|
28
28
|
pushChanges();
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
+
export function moveTop(element) {
|
|
32
|
+
if (!orderAttrib)
|
|
33
|
+
return;
|
|
34
|
+
let current = getFirst(objects);
|
|
35
|
+
if (current == element)
|
|
36
|
+
return;
|
|
37
|
+
const firstOrder = current[orderAttrib];
|
|
38
|
+
while (current != element) {
|
|
39
|
+
const next = getNext(objects, current);
|
|
40
|
+
const nextOrder = next[orderAttrib];
|
|
41
|
+
current[orderAttrib] = nextOrder;
|
|
42
|
+
informModification(current, orderAttrib);
|
|
43
|
+
current = next;
|
|
44
|
+
}
|
|
45
|
+
element[orderAttrib] = firstOrder;
|
|
46
|
+
informModification(element, orderAttrib);
|
|
47
|
+
objects = remove(objects, element);
|
|
48
|
+
objects = insertAt(objects, 0, element);
|
|
49
|
+
pushChanges();
|
|
50
|
+
}
|
|
31
51
|
export function moveDown(element) {
|
|
32
52
|
if (!orderAttrib)
|
|
33
53
|
return;
|
|
@@ -73,9 +93,9 @@ function onBlurInserter() {
|
|
|
73
93
|
}
|
|
74
94
|
</script>
|
|
75
95
|
|
|
76
|
-
{#each objects as item (item.Id)}
|
|
96
|
+
{#each objects as item, idx (item.Id)}
|
|
77
97
|
{#key item} <!-- Forces to fully rerender when item changed to fire use: callbacks again -->
|
|
78
|
-
<slot {item}/>
|
|
98
|
+
<slot {item} {idx}/>
|
|
79
99
|
{/key}
|
|
80
100
|
{/each }
|
|
81
101
|
|
|
@@ -9,6 +9,7 @@ declare const __propDef: {
|
|
|
9
9
|
MIN_ORDER?: 0 | undefined;
|
|
10
10
|
reload?: ((_objects: object[]) => void) | undefined;
|
|
11
11
|
moveUp?: ((element: object) => void) | undefined;
|
|
12
|
+
moveTop?: ((element: object) => void) | undefined;
|
|
12
13
|
moveDown?: ((element: object) => void) | undefined;
|
|
13
14
|
add?: ((onAddHandler: Function) => Promise<void>) | undefined;
|
|
14
15
|
};
|
|
@@ -18,6 +19,7 @@ declare const __propDef: {
|
|
|
18
19
|
slots: {
|
|
19
20
|
default: {
|
|
20
21
|
item: object;
|
|
22
|
+
idx: any;
|
|
21
23
|
};
|
|
22
24
|
};
|
|
23
25
|
};
|
|
@@ -29,6 +31,7 @@ export default class Sidebar extends SvelteComponentTyped<SidebarProps, SidebarE
|
|
|
29
31
|
get MIN_ORDER(): 0;
|
|
30
32
|
get reload(): (_objects: object[]) => void;
|
|
31
33
|
get moveUp(): (element: object) => void;
|
|
34
|
+
get moveTop(): (element: object) => void;
|
|
32
35
|
get moveDown(): (element: object) => void;
|
|
33
36
|
get add(): (onAddHandler: Function) => Promise<void>;
|
|
34
37
|
}
|
package/package.json
CHANGED
package/utils.js
CHANGED
|
@@ -105,13 +105,15 @@ export function editable(node, params)
|
|
|
105
105
|
let active = false;
|
|
106
106
|
let onRemove = undefined;
|
|
107
107
|
let onFinish = undefined;
|
|
108
|
+
let onSoftEnter = undefined;
|
|
108
109
|
if(params instanceof Object)
|
|
109
110
|
{
|
|
110
111
|
action = params.action ?? params;
|
|
111
112
|
active = params.active ?? false;
|
|
112
113
|
onRemove = params.remove ?? undefined
|
|
113
114
|
onFinish = params.onFinish ?? undefined
|
|
114
|
-
|
|
115
|
+
onSoftEnter = params.onSoftEnter ?? undefined;
|
|
116
|
+
|
|
115
117
|
if(params.readonly)
|
|
116
118
|
return;
|
|
117
119
|
}
|
|
@@ -131,7 +133,7 @@ export function editable(node, params)
|
|
|
131
133
|
if(observer)
|
|
132
134
|
observer.disconnect();
|
|
133
135
|
|
|
134
|
-
await finish_editing(cancel
|
|
136
|
+
await finish_editing({cancel: cancel});
|
|
135
137
|
}
|
|
136
138
|
|
|
137
139
|
const key_listener = async (e) =>
|
|
@@ -146,7 +148,7 @@ export function editable(node, params)
|
|
|
146
148
|
e.stopPropagation();
|
|
147
149
|
e.preventDefault();
|
|
148
150
|
|
|
149
|
-
await finish_editing(true
|
|
151
|
+
await finish_editing({ cancel: true });
|
|
150
152
|
}
|
|
151
153
|
break;
|
|
152
154
|
|
|
@@ -154,7 +156,10 @@ export function editable(node, params)
|
|
|
154
156
|
e.stopPropagation();
|
|
155
157
|
e.preventDefault();
|
|
156
158
|
|
|
157
|
-
|
|
159
|
+
if(e.shiftKey && onSoftEnter)
|
|
160
|
+
await finish_editing({ softEnter: true});
|
|
161
|
+
else
|
|
162
|
+
await finish_editing({ incremental: true});
|
|
158
163
|
break;
|
|
159
164
|
|
|
160
165
|
case 'Backspace':
|
|
@@ -162,15 +167,19 @@ export function editable(node, params)
|
|
|
162
167
|
{
|
|
163
168
|
e.stopPropagation();
|
|
164
169
|
e.preventDefault();
|
|
165
|
-
//await finish_editing(false, false);
|
|
166
170
|
onRemove();
|
|
167
171
|
}
|
|
168
172
|
break;
|
|
169
173
|
}
|
|
170
174
|
}
|
|
171
175
|
|
|
172
|
-
const finish_editing = async (cancel, incremental) =>
|
|
176
|
+
//const finish_editing = async (softEnter, cancel, incremental) =>
|
|
177
|
+
const finish_editing = async (params) =>
|
|
173
178
|
{
|
|
179
|
+
const softEnter = params.softEnter ?? false;
|
|
180
|
+
const cancel = params.cancel ?? false;
|
|
181
|
+
const incremental = params.incremental ?? false;
|
|
182
|
+
|
|
174
183
|
if(!active)
|
|
175
184
|
{
|
|
176
185
|
node.removeEventListener("blur", blur_listener);
|
|
@@ -186,6 +195,10 @@ export function editable(node, params)
|
|
|
186
195
|
{
|
|
187
196
|
node.innerHTML = org_text;
|
|
188
197
|
}
|
|
198
|
+
else if(softEnter)
|
|
199
|
+
{
|
|
200
|
+
onSoftEnter(node.textContent)
|
|
201
|
+
}
|
|
189
202
|
else if(action)
|
|
190
203
|
{
|
|
191
204
|
if(active)
|
|
@@ -202,7 +215,8 @@ export function editable(node, params)
|
|
|
202
215
|
detail:
|
|
203
216
|
{
|
|
204
217
|
cancel: cancel,
|
|
205
|
-
incremental: incremental
|
|
218
|
+
incremental: incremental,
|
|
219
|
+
softEnter: softEnter
|
|
206
220
|
}
|
|
207
221
|
});
|
|
208
222
|
|