@humandialog/forms.svelte 1.4.0 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/Fab.svelte +42 -22
- package/components/contextmenu.svelte +30 -11
- package/components/document/internal/palette.svelte +2 -0
- package/components/kanban/internal/kanban.card.svelte +15 -9
- package/components/kanban/internal/kanban.props.svelte +1 -1
- package/components/list/internal/list.element.svelte +13 -12
- package/components/menu.js +4 -0
- package/components/sidebar/sidebar.item.svelte +48 -15
- package/horizontal.toolbar.svelte +41 -14
- package/horizontal.toolbar.svelte.d.ts +6 -2
- package/index.d.ts +2 -1
- package/index.js +2 -1
- package/operations.svelte +13 -10
- package/package.json +1 -1
- package/tenant.members.svelte +2 -0
- package/vertical.toolbar.svelte +51 -23
- package/vertical.toolbar.svelte.d.ts +6 -2
package/components/Fab.svelte
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { contextToolbarOperations, pageToolbarOperations, contextItemsStore, toolsActionsOperations } from "../stores.js";
|
|
3
3
|
import { showFloatingToolbar, showMenu, showGridMenu } from "./menu.js";
|
|
4
4
|
import { FaChevronUp, FaChevronDown, FaChevronLeft, FaChevronRight, FaCircle, FaEllipsisV } from "svelte-icons/fa/";
|
|
5
|
+
import { isDeviceSmallerThan } from "../utils.js";
|
|
5
6
|
$:
|
|
6
7
|
setupCurrentContextOperations($pageToolbarOperations, $contextToolbarOperations, $toolsActionsOperations);
|
|
7
8
|
let operations = [];
|
|
@@ -14,12 +15,14 @@ let hToolboxExpanded = false;
|
|
|
14
15
|
let isDirectPositioningMode = false;
|
|
15
16
|
function setupCurrentContextOperations(...args) {
|
|
16
17
|
let opVer = 0;
|
|
18
|
+
let main_FAB_position = "";
|
|
17
19
|
isDirectPositioningMode = false;
|
|
18
20
|
if ($toolsActionsOperations && Array.isArray($toolsActionsOperations) && toolsActionsOperations.length > 0) {
|
|
19
21
|
operations = $toolsActionsOperations;
|
|
20
22
|
} else if ($toolsActionsOperations && $toolsActionsOperations.operations && $toolsActionsOperations.operations.length > 0) {
|
|
21
23
|
operations = $toolsActionsOperations.operations;
|
|
22
24
|
opVer = $toolsActionsOperations.opver ?? 0;
|
|
25
|
+
main_FAB_position = $toolsActionsOperations.fab ?? "";
|
|
23
26
|
if (opVer > 0)
|
|
24
27
|
isDirectPositioningMode = true;
|
|
25
28
|
} else if ($contextToolbarOperations && Array.isArray($contextToolbarOperations) && $contextToolbarOperations.length > 0) {
|
|
@@ -27,6 +30,7 @@ function setupCurrentContextOperations(...args) {
|
|
|
27
30
|
} else if ($contextToolbarOperations && $contextToolbarOperations.operations && $contextToolbarOperations.operations.length > 0) {
|
|
28
31
|
operations = $contextToolbarOperations.operations;
|
|
29
32
|
opVer = $contextToolbarOperations.opver ?? 0;
|
|
33
|
+
main_FAB_position = $contextToolbarOperations.fab ?? "";
|
|
30
34
|
if (opVer > 0)
|
|
31
35
|
isDirectPositioningMode = true;
|
|
32
36
|
} else {
|
|
@@ -35,6 +39,7 @@ function setupCurrentContextOperations(...args) {
|
|
|
35
39
|
else {
|
|
36
40
|
operations = $pageToolbarOperations.operations;
|
|
37
41
|
opVer = $pageToolbarOperations.opver ?? 0;
|
|
42
|
+
main_FAB_position = $pageToolbarOperations.fab ?? "";
|
|
38
43
|
if (opVer > 0)
|
|
39
44
|
isDirectPositioningMode = true;
|
|
40
45
|
}
|
|
@@ -46,28 +51,38 @@ function setupCurrentContextOperations(...args) {
|
|
|
46
51
|
});
|
|
47
52
|
operations = flatOperations;
|
|
48
53
|
} else if (opVer == 2) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
flatOperations
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
const definedOperations = [...operations];
|
|
55
|
+
if (main_FAB_position) {
|
|
56
|
+
let flatOperations = [];
|
|
57
|
+
definedOperations.forEach((group) => {
|
|
58
|
+
flatOperations.push({
|
|
59
|
+
caption: group.caption,
|
|
60
|
+
separator: true
|
|
61
|
+
});
|
|
62
|
+
flatOperations = [...flatOperations, ...group.operations];
|
|
63
|
+
});
|
|
64
|
+
const realOps = flatOperations.filter((el) => !!el.separator == false);
|
|
65
|
+
if (realOps.length > 1) {
|
|
66
|
+
mainOperation = {
|
|
67
|
+
icon: FaEllipsisV,
|
|
68
|
+
menu: flatOperations,
|
|
69
|
+
fab: main_FAB_position
|
|
70
|
+
};
|
|
71
|
+
operations = [mainOperation];
|
|
72
|
+
} else if (realOps.length == 1) {
|
|
73
|
+
mainOperation = realOps[0];
|
|
74
|
+
mainOperation["fab"] = main_FAB_position;
|
|
75
|
+
operations = [mainOperation];
|
|
76
|
+
} else
|
|
77
|
+
operations = [];
|
|
78
|
+
}
|
|
79
|
+
definedOperations.forEach((group) => {
|
|
80
|
+
group.operations.forEach((op) => {
|
|
81
|
+
if (op.fab) {
|
|
82
|
+
operations = [...operations, op];
|
|
83
|
+
}
|
|
54
84
|
});
|
|
55
|
-
flatOperations = [...flatOperations, ...group.operations];
|
|
56
85
|
});
|
|
57
|
-
const realOps = flatOperations.filter((el) => !!el.separator == false);
|
|
58
|
-
if (realOps.length > 1) {
|
|
59
|
-
mainOperation = {
|
|
60
|
-
icon: FaEllipsisV,
|
|
61
|
-
menu: flatOperations,
|
|
62
|
-
fab: "M00"
|
|
63
|
-
};
|
|
64
|
-
operations = [mainOperation];
|
|
65
|
-
} else if (realOps.length == 1) {
|
|
66
|
-
mainOperation = realOps[0];
|
|
67
|
-
mainOperation["fab"] = "M00";
|
|
68
|
-
operations = [mainOperation];
|
|
69
|
-
} else
|
|
70
|
-
operations = [];
|
|
71
86
|
} else {
|
|
72
87
|
if (operations.length > 0)
|
|
73
88
|
mainOperation = operations[0];
|
|
@@ -115,12 +130,17 @@ function on_click(e, operation) {
|
|
|
115
130
|
rect.y -= margin;
|
|
116
131
|
rect.width += 2 * margin;
|
|
117
132
|
rect.height += 2 * margin;
|
|
133
|
+
const mobile = isDeviceSmallerThan("sm");
|
|
118
134
|
if (operation.menu)
|
|
119
135
|
showMenu(rect, operation.menu);
|
|
120
136
|
else if (operation.toolbar)
|
|
121
137
|
showFloatingToolbar(rect, operation.toolbar, operation.props ?? {});
|
|
122
|
-
else if (operation.grid)
|
|
123
|
-
|
|
138
|
+
else if (operation.grid) {
|
|
139
|
+
if (mobile)
|
|
140
|
+
showMenu(rect, operation.grid);
|
|
141
|
+
else
|
|
142
|
+
showGridMenu(rect, operation.grid);
|
|
143
|
+
}
|
|
124
144
|
}
|
|
125
145
|
function toggleExpandToolboxV(e) {
|
|
126
146
|
vToolboxExpanded = !vToolboxExpanded;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import Icon from "./icon.svelte";
|
|
3
3
|
import { contextItemsStore, pushToolsActionsOperations, popToolsActionsOperations } from "../stores";
|
|
4
4
|
import { isDeviceSmallerThan, isOnScreenKeyboardVisible } from "../utils";
|
|
5
|
-
import { hideWholeContextMenu } from "./menu";
|
|
5
|
+
import { hideWholeContextMenu, showMenu, showFloatingToolbar, showGridMenu } from "./menu";
|
|
6
6
|
import { FaTimes } from "svelte-icons/fa";
|
|
7
7
|
export let widthPx = 400;
|
|
8
8
|
export let menu_items_id_prefix = "__hd_svelte_menuitem_";
|
|
@@ -181,7 +181,7 @@ function on_keydown(e, operation, index) {
|
|
|
181
181
|
hide_submenu();
|
|
182
182
|
break;
|
|
183
183
|
case "Enter":
|
|
184
|
-
execute_action(operation, index);
|
|
184
|
+
execute_action(void 0, operation, index);
|
|
185
185
|
e.preventDefault();
|
|
186
186
|
e.stopPropagation();
|
|
187
187
|
break;
|
|
@@ -219,7 +219,7 @@ function on_mouse_move(index) {
|
|
|
219
219
|
if (!isDeviceSmallerThan("sm"))
|
|
220
220
|
focus_menu_item(index);
|
|
221
221
|
}
|
|
222
|
-
function execute_action(operation, index) {
|
|
222
|
+
function execute_action(e, operation, index) {
|
|
223
223
|
if (operation.menu) {
|
|
224
224
|
focus_menu_item(index);
|
|
225
225
|
return;
|
|
@@ -227,12 +227,29 @@ function execute_action(operation, index) {
|
|
|
227
227
|
hideWholeContextMenu();
|
|
228
228
|
if (!operation)
|
|
229
229
|
return;
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
if (
|
|
234
|
-
|
|
235
|
-
|
|
230
|
+
let owner = e.target;
|
|
231
|
+
while (owner && owner.tagName != "BUTTON")
|
|
232
|
+
owner = owner.parentElement;
|
|
233
|
+
if (operation.preAction)
|
|
234
|
+
operation.preAction(owner);
|
|
235
|
+
const mobile = isDeviceSmallerThan("sm");
|
|
236
|
+
if (operation.action) {
|
|
237
|
+
operation.action(owner, around_rect);
|
|
238
|
+
} else {
|
|
239
|
+
let rect;
|
|
240
|
+
if (around_rect)
|
|
241
|
+
rect = around_rect;
|
|
242
|
+
else
|
|
243
|
+
rect = owner.getBoundingClientRect();
|
|
244
|
+
if (operation.toolbar)
|
|
245
|
+
showFloatingToolbar(rect, operation.toolbar, operation.props ?? {});
|
|
246
|
+
else if (operation.grid) {
|
|
247
|
+
if (mobile)
|
|
248
|
+
showMenu(rect, operation.grid);
|
|
249
|
+
else
|
|
250
|
+
showGridMenu(rect, operation.grid);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
236
253
|
}
|
|
237
254
|
function focus_menu_item(index) {
|
|
238
255
|
const operation = operations[index];
|
|
@@ -290,7 +307,9 @@ function calculateBackground(is_highlighted, active) {
|
|
|
290
307
|
</script>
|
|
291
308
|
|
|
292
309
|
<div id="__hd_svelte_contextmenu"
|
|
293
|
-
class=" bg-white dark:bg-stone-800
|
|
310
|
+
class=" bg-white dark:bg-stone-800
|
|
311
|
+
text-stone-800 dark:text-stone-400 rounded-lg border
|
|
312
|
+
border-stone-200 dark:border-stone-700 shadow-md
|
|
294
313
|
z-30 fixed min-w-[{min_width_px}px] w-max overflow-y-auto"
|
|
295
314
|
style={css_position}
|
|
296
315
|
bind:this={menu_root}>
|
|
@@ -317,7 +336,7 @@ function calculateBackground(is_highlighted, active) {
|
|
|
317
336
|
<button class="block w-full pr-4 text-left flex flex-row cursor-context-menu {active} focus:outline-none"
|
|
318
337
|
id={menu_item_id}
|
|
319
338
|
bind:this={menu_items[index]}
|
|
320
|
-
on:click|stopPropagation={(e) => { execute_action(operation, index) } }
|
|
339
|
+
on:click|stopPropagation={(e) => { execute_action(e, operation, index) } }
|
|
321
340
|
on:mouseenter = {(e) => {on_mouse_move(index)}}
|
|
322
341
|
on:keydown|stopPropagation={(e) => on_keydown(e, operation, index)}
|
|
323
342
|
on:mousedown={mousedown}
|
|
@@ -39,6 +39,8 @@ afterUpdate(
|
|
|
39
39
|
visible && paletteElement
|
|
40
40
|
) {
|
|
41
41
|
let layoutRoot = document.getElementById("__hd_svelte_layout_root");
|
|
42
|
+
if (!layoutRoot)
|
|
43
|
+
layoutRoot = document.getElementById("app");
|
|
42
44
|
if (!!layoutRoot && paletteElement.parentElement != layoutRoot) {
|
|
43
45
|
await tick();
|
|
44
46
|
layoutRoot.appendChild(paletteElement);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script>import { getContext, tick } from "svelte";
|
|
2
|
-
import { push } from "svelte-spa-router";
|
|
2
|
+
import { push, link } from "svelte-spa-router";
|
|
3
3
|
import {
|
|
4
4
|
contextItemsStore,
|
|
5
5
|
isActive,
|
|
@@ -137,9 +137,9 @@ export async function editProperty(field) {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
function followDefinedHRef() {
|
|
140
|
-
let
|
|
141
|
-
if (
|
|
142
|
-
push(
|
|
140
|
+
let link2 = getHRef();
|
|
141
|
+
if (link2)
|
|
142
|
+
push(link2);
|
|
143
143
|
}
|
|
144
144
|
function getHRef() {
|
|
145
145
|
if (definition.titleHref)
|
|
@@ -221,12 +221,18 @@ function showAttachementIcon() {
|
|
|
221
221
|
onSoftEnter: async (text) => { onTitleChanged(text); await editProperty('Summary') }
|
|
222
222
|
}}
|
|
223
223
|
use:conditionalClick={{
|
|
224
|
-
condition:
|
|
224
|
+
condition: hasOpen,
|
|
225
225
|
callback: performOpen}}
|
|
226
226
|
bind:this={titleElement}>
|
|
227
|
-
|
|
227
|
+
|
|
228
|
+
{#if isLinkLike}
|
|
229
|
+
<a href={getHRef()} use:link>
|
|
230
|
+
{item[definition.titleAttrib]}
|
|
231
|
+
</a>
|
|
232
|
+
{:else}
|
|
228
233
|
{item[definition.titleAttrib]}
|
|
229
|
-
|
|
234
|
+
{/if}
|
|
235
|
+
|
|
230
236
|
|
|
231
237
|
{#if showIcon}
|
|
232
238
|
<span id="attachement" class="absolute top-1 right-0 w-5 h-5 sm:w-3 sm:h-3">
|
|
@@ -263,7 +269,7 @@ function showAttachementIcon() {
|
|
|
263
269
|
{#if isCardActive}
|
|
264
270
|
<p class=" text-sm sm:text-sm
|
|
265
271
|
|
|
266
|
-
text-stone-400
|
|
272
|
+
text-stone-600 dark:text-stone-400
|
|
267
273
|
|
|
268
274
|
overflow-hidden"
|
|
269
275
|
use:editable={{
|
|
@@ -277,7 +283,7 @@ function showAttachementIcon() {
|
|
|
277
283
|
{:else}
|
|
278
284
|
<p class=" text-sm sm:text-sm
|
|
279
285
|
|
|
280
|
-
text-stone-400
|
|
286
|
+
text-stone-600 dark:text-stone-400
|
|
281
287
|
|
|
282
288
|
overflow-hidden">
|
|
283
289
|
{item[definition.summaryAttrib]}
|
|
@@ -15,7 +15,7 @@ import Summary from "./list.element.summary.svelte";
|
|
|
15
15
|
import Properties from "./list.element.props.svelte";
|
|
16
16
|
import { isDeviceSmallerThan } from "../../../utils";
|
|
17
17
|
import { rList_definition, rList_property_type } from "../List";
|
|
18
|
-
import { push } from "svelte-spa-router";
|
|
18
|
+
import { push, link } from "svelte-spa-router";
|
|
19
19
|
import { FaExternalLinkAlt } from "svelte-icons/fa/";
|
|
20
20
|
import Tags from "../../tags.svelte";
|
|
21
21
|
export let item;
|
|
@@ -151,9 +151,9 @@ function on_active_row_clicked(e, part) {
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
function followDefinedHRef() {
|
|
154
|
-
let
|
|
155
|
-
if (
|
|
156
|
-
push(
|
|
154
|
+
let link2 = getHRef();
|
|
155
|
+
if (link2)
|
|
156
|
+
push(link2);
|
|
157
157
|
}
|
|
158
158
|
function getHRef() {
|
|
159
159
|
if (definition.title_href)
|
|
@@ -252,7 +252,7 @@ export function scrollToView() {
|
|
|
252
252
|
{#if item}
|
|
253
253
|
{@const element_title = item[title]}
|
|
254
254
|
|
|
255
|
-
<section class="my-1 flex flex-row w-full text-stone-
|
|
255
|
+
<section class="my-1 flex flex-row w-full text-stone-900 dark:text-stone-300 cursor-default rounded-md border border-transparent {selected_class} {focused_class} scroll-mt-[50px] sm:scroll-mt-[40px]"
|
|
256
256
|
role="menu"
|
|
257
257
|
tabindex="-1"
|
|
258
258
|
bind:this={rootElement}> <!-- on:contextmenu={on_contextmenu} -->
|
|
@@ -273,18 +273,19 @@ export function scrollToView() {
|
|
|
273
273
|
{#if is_link_like}
|
|
274
274
|
<p class=" text-base font-semibold
|
|
275
275
|
|
|
276
|
-
whitespace-nowrap overflow-clip w-full sm:flex-none sm:{name_w}
|
|
277
|
-
sm:hover:cursor-pointer underline"
|
|
276
|
+
whitespace-nowrap overflow-clip w-full sm:flex-none sm:{name_w}"
|
|
278
277
|
id="__hd_list_ctrl_{getItemKey(item)}_Title"
|
|
279
|
-
on:click|stopPropagation={followDefinedHRef}
|
|
280
278
|
use:editable={{
|
|
281
279
|
action: (text) => {change_name(text)},
|
|
282
280
|
active: false,
|
|
283
281
|
readonly: definition.title_readonly,
|
|
284
282
|
onSoftEnter: (text) => {change_name(text); editProperty('Summary')}
|
|
285
283
|
}}
|
|
286
|
-
>
|
|
287
|
-
|
|
284
|
+
> <!--on:click|stopPropagation={followDefinedHRef}-->
|
|
285
|
+
<a class="sm:hover:cursor-pointer underline"
|
|
286
|
+
href={getHRef()} use:link>
|
|
287
|
+
{element_title}
|
|
288
|
+
</a>
|
|
288
289
|
</p>
|
|
289
290
|
{:else}
|
|
290
291
|
<p class=" text-base font-semibold
|
|
@@ -332,7 +333,7 @@ export function scrollToView() {
|
|
|
332
333
|
{#if is_row_active}
|
|
333
334
|
<p id={element_id}
|
|
334
335
|
class=" text-sm
|
|
335
|
-
text-stone-400"
|
|
336
|
+
text-stone-600 dark:text-stone-400"
|
|
336
337
|
use:editable={{
|
|
337
338
|
action: (text) => {change_summary(text)},
|
|
338
339
|
readonly: definition.summary_readonly,
|
|
@@ -344,7 +345,7 @@ export function scrollToView() {
|
|
|
344
345
|
{:else}
|
|
345
346
|
<p id={element_id}
|
|
346
347
|
class=" text-sm
|
|
347
|
-
text-stone-400"
|
|
348
|
+
text-stone-600 dark:text-stone-400"
|
|
348
349
|
on:click={(e) => on_active_row_clicked(e, 'bottom')}>
|
|
349
350
|
{item[summary]}
|
|
350
351
|
</p>
|
package/components/menu.js
CHANGED
|
@@ -7,6 +7,8 @@ export function showMenu(around, operations) {
|
|
|
7
7
|
let menu_element = document.getElementById("__hd_svelte_contextmenu");
|
|
8
8
|
if (!menu_element) {
|
|
9
9
|
let app_div = document.getElementById("__hd_svelte_layout_root");
|
|
10
|
+
if (!app_div)
|
|
11
|
+
app_div = document.getElementById("app");
|
|
10
12
|
menu_comopnent = new Menu({
|
|
11
13
|
target: app_div,
|
|
12
14
|
props: {}
|
|
@@ -32,6 +34,8 @@ export function showFloatingToolbar(around, toolbar, props = {}) {
|
|
|
32
34
|
let floating_container = document.getElementById("__hd_svelte_floating_container");
|
|
33
35
|
if (!floating_container) {
|
|
34
36
|
let app_div = document.getElementById("__hd_svelte_layout_root");
|
|
37
|
+
if (!app_div)
|
|
38
|
+
app_div = document.getElementById("app");
|
|
35
39
|
toolbar_component = new Floating_container({
|
|
36
40
|
target: app_div,
|
|
37
41
|
props: {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>import { getContext, tick } from "svelte";
|
|
2
2
|
import Icon from "../icon.svelte";
|
|
3
3
|
import { contextItemsStore, auto_hide_sidebar, contextToolbarOperations } from "../../stores";
|
|
4
|
-
import { FaBars,
|
|
4
|
+
import { FaBars, FaEllipsisV } from "svelte-icons/fa";
|
|
5
5
|
import { link, push } from "svelte-spa-router";
|
|
6
6
|
import {
|
|
7
7
|
selectable as _selectable,
|
|
@@ -184,9 +184,9 @@ function activateRow(e) {
|
|
|
184
184
|
caption: "View",
|
|
185
185
|
operations: [
|
|
186
186
|
{
|
|
187
|
-
icon:
|
|
187
|
+
icon: FaEllipsisV,
|
|
188
188
|
menu: operationsList,
|
|
189
|
-
fab: "
|
|
189
|
+
fab: "M00"
|
|
190
190
|
}
|
|
191
191
|
]
|
|
192
192
|
}
|
|
@@ -218,19 +218,52 @@ function activateRow(e) {
|
|
|
218
218
|
<div class="flex flex-row justify-between
|
|
219
219
|
text-base font-semibold">
|
|
220
220
|
{#if href}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
221
|
+
{#if isOnPage}
|
|
222
|
+
{#if isRowActive}
|
|
223
|
+
<a on:click={on_link_clicked}
|
|
224
|
+
href={href}
|
|
225
|
+
use:link
|
|
226
|
+
class="flex-1 ml-2 inline-flex items-center underline"
|
|
227
|
+
>
|
|
228
|
+
{#if icon}
|
|
229
|
+
<Icon class="w-5 h-5 mt-0.5 ml-2 mr-1" component={icon}/>
|
|
230
|
+
|
|
231
|
+
{/if}
|
|
232
|
+
<span class="ml-3"
|
|
233
|
+
use:editable_if_needed={editable}>
|
|
234
|
+
<slot/>
|
|
235
|
+
</span>
|
|
236
|
+
</a>
|
|
237
|
+
{:else}
|
|
238
|
+
<span on:click={on_link_clicked}
|
|
239
|
+
class="flex-1 ml-2 inline-flex items-center"
|
|
240
|
+
>
|
|
241
|
+
{#if icon}
|
|
242
|
+
<Icon class="w-5 h-5 mt-0.5 ml-2 mr-1" component={icon}/>
|
|
243
|
+
|
|
244
|
+
{/if}
|
|
245
|
+
<span class="ml-3"
|
|
246
|
+
use:editable_if_needed={editable}>
|
|
247
|
+
<slot/>
|
|
248
|
+
</span>
|
|
249
|
+
</span>
|
|
228
250
|
{/if}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
251
|
+
{:else}
|
|
252
|
+
<a on:click={on_link_clicked}
|
|
253
|
+
href={href}
|
|
254
|
+
use:link
|
|
255
|
+
class="flex-1 ml-2 inline-flex items-center group"
|
|
256
|
+
>
|
|
257
|
+
{#if icon}
|
|
258
|
+
<Icon class="w-5 h-5 mt-0.5 ml-2 mr-1" component={icon}/>
|
|
259
|
+
|
|
260
|
+
{/if}
|
|
261
|
+
<span class="ml-3 group-hover:underline"
|
|
262
|
+
use:editable_if_needed={editable}>
|
|
263
|
+
<slot/>
|
|
264
|
+
</span>
|
|
265
|
+
</a>
|
|
266
|
+
{/if}
|
|
234
267
|
{:else}
|
|
235
268
|
<p class="flex-1 ml-2 inline-flex items-center group cursor-default"
|
|
236
269
|
use:selectable_if_needed={selectable}>
|
|
@@ -27,8 +27,11 @@
|
|
|
27
27
|
import { isDeviceSmallerThan, isOnNavigationPage, pushNavigationPage, popNavigationPage } from './utils.js';
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
export let appConfig;
|
|
30
|
+
export let appConfig = undefined;
|
|
31
31
|
export let clearsContext = 'sel props'
|
|
32
|
+
|
|
33
|
+
export let definedTabs = undefined
|
|
34
|
+
export let mainToolbarConfig = undefined
|
|
32
35
|
|
|
33
36
|
let config = null;
|
|
34
37
|
let has_selection_details = false;
|
|
@@ -45,23 +48,39 @@
|
|
|
45
48
|
|
|
46
49
|
$:
|
|
47
50
|
{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
if(appConfig)
|
|
52
|
+
{
|
|
53
|
+
config = appConfig.mainToolbar;
|
|
54
|
+
has_selection_details = appConfig.selectionDetails;
|
|
55
|
+
if(has_selection_details)
|
|
56
|
+
selection_details_caption = appConfig.selectionDetails.caption ?? 'Properties';
|
|
57
|
+
}
|
|
58
|
+
else
|
|
59
|
+
{
|
|
60
|
+
config = mainToolbarConfig
|
|
61
|
+
has_selection_details = false
|
|
62
|
+
}
|
|
63
|
+
|
|
52
64
|
is_logged_in = $session.isActive;
|
|
53
65
|
show_sign_in_out_icons = config.signin ? true : false;
|
|
54
66
|
sign_in_href = $signInHRef;
|
|
55
67
|
sign_out_href = $signOutHRef;
|
|
56
68
|
//user_is_in_multiple_groups = $session.tenants.length > 1
|
|
57
69
|
|
|
58
|
-
|
|
59
|
-
if(tabs.length > 1)
|
|
60
|
-
icon = FaBars;
|
|
61
|
-
else
|
|
70
|
+
if(definedTabs && Array.isArray(definedTabs) && definedTabs.length > 0)
|
|
62
71
|
{
|
|
63
|
-
|
|
64
|
-
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
else
|
|
75
|
+
{
|
|
76
|
+
tabs = Object.keys(appConfig.sidebar);
|
|
77
|
+
if(tabs.length > 1)
|
|
78
|
+
icon = FaBars;
|
|
79
|
+
else
|
|
80
|
+
{
|
|
81
|
+
let first_tab = appConfig.sidebar[tabs[0]];
|
|
82
|
+
icon = first_tab.icon;
|
|
83
|
+
}
|
|
65
84
|
}
|
|
66
85
|
}
|
|
67
86
|
|
|
@@ -283,9 +302,17 @@
|
|
|
283
302
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
284
303
|
<div class="no-print flex flex-row w-full" on:click={clearSelection}>
|
|
285
304
|
<div class="flex-none left-0 flex h-12 sm:h-10">
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
305
|
+
{#if definedTabs && definedTabs.length > 0}
|
|
306
|
+
{#each definedTabs as tab}
|
|
307
|
+
<button class="w-12 sm:w-10 h-full flex justify-center items-center text-stone-300 hover:text-stone-100" on:click={tab.onclick}>
|
|
308
|
+
<Icon class="w-5 h-5" component={tab.icon}/>
|
|
309
|
+
</button>
|
|
310
|
+
{/each}
|
|
311
|
+
{:else}
|
|
312
|
+
<button class="w-12 sm:w-10 h-full flex justify-center items-center text-stone-300 hover:text-stone-100" on:click|stopPropagation={toggle_navigator}>
|
|
313
|
+
<Icon class="w-5 h-5" component={icon}/>
|
|
314
|
+
</button>
|
|
315
|
+
{/if}
|
|
289
316
|
</div>
|
|
290
317
|
|
|
291
318
|
<div class="grow">
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
/** @typedef {typeof __propDef.events} HorizontalEvents */
|
|
3
3
|
/** @typedef {typeof __propDef.slots} HorizontalSlots */
|
|
4
4
|
export default class Horizontal extends SvelteComponentTyped<{
|
|
5
|
-
appConfig
|
|
5
|
+
appConfig?: any;
|
|
6
6
|
clearsContext?: string | undefined;
|
|
7
|
+
definedTabs?: any;
|
|
8
|
+
mainToolbarConfig?: any;
|
|
7
9
|
}, {
|
|
8
10
|
[evt: string]: CustomEvent<any>;
|
|
9
11
|
}, {}> {
|
|
@@ -14,8 +16,10 @@ export type HorizontalSlots = typeof __propDef.slots;
|
|
|
14
16
|
import { SvelteComponentTyped } from "svelte";
|
|
15
17
|
declare const __propDef: {
|
|
16
18
|
props: {
|
|
17
|
-
appConfig
|
|
19
|
+
appConfig?: any;
|
|
18
20
|
clearsContext?: string | undefined;
|
|
21
|
+
definedTabs?: any;
|
|
22
|
+
mainToolbarConfig?: any;
|
|
19
23
|
};
|
|
20
24
|
events: {
|
|
21
25
|
[evt: string]: CustomEvent<any>;
|
package/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { default as Box } from "./form.box.svelte";
|
|
|
5
5
|
export { default as Operations } from './operations.svelte';
|
|
6
6
|
export { default as Layout } from './desk.svelte';
|
|
7
7
|
export { default as VerticalToolbar } from './vertical.toolbar.svelte';
|
|
8
|
+
export { default as HorizontalToolbar } from './horizontal.toolbar.svelte';
|
|
8
9
|
export { default as Icon } from "./components/icon.svelte";
|
|
9
10
|
export { default as IconT } from "./components/icon.ex.svelte";
|
|
10
11
|
export { default as Button } from './components/button.svelte';
|
|
@@ -58,7 +59,7 @@ export { default as KanbanCallbacks } from './components/kanban/kanban.callbacks
|
|
|
58
59
|
export { KanbanColumnTop, KanbanColumnBottom } from './components/kanban/Kanban';
|
|
59
60
|
export { selectItem, activateItem, clearActiveItem, isActive, isSelected, getActive, editable, startEditing, saveCurrentEditable, selectable, handleSelect, isDeviceSmallerThan, resizeImage, refreshToolbarOperations, isOnScreenKeyboardVisible, randomString, UI, } from './utils';
|
|
60
61
|
export { getNiceStringDateTime, getFormattedStringDate, getNiceStringDate, dayName, monthName } from './components/date_utils';
|
|
61
|
-
export { mainContentPageReloader, reloadMainContentPage, reloadWholeApp, alerts, addAlert, onErrorShowAlert, main_sidebar_visible_store, tagsReloader, reloadVisibleTags } from './stores.js';
|
|
62
|
+
export { mainContentPageReloader, reloadMainContentPage, reloadWholeApp, alerts, addAlert, onErrorShowAlert, main_sidebar_visible_store, tagsReloader, reloadVisibleTags, dark_mode_store } from './stores.js';
|
|
62
63
|
export { data_tick_store, // tmp
|
|
63
64
|
hasSelectedItem, hasDataItem, setNavigatorTitle } from "./stores";
|
|
64
65
|
export { contextToolbarOperations, pageToolbarOperations, contextItemsStore, contextTypesStore } from './stores';
|
package/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export { default as Box } from "./form.box.svelte";
|
|
|
9
9
|
export { default as Operations } from './operations.svelte';
|
|
10
10
|
export { default as Layout } from './desk.svelte';
|
|
11
11
|
export { default as VerticalToolbar } from './vertical.toolbar.svelte';
|
|
12
|
+
export { default as HorizontalToolbar } from './horizontal.toolbar.svelte';
|
|
12
13
|
// @ts-ignore
|
|
13
14
|
export { default as Icon } from "./components/icon.svelte";
|
|
14
15
|
export { default as IconT } from "./components/icon.ex.svelte";
|
|
@@ -64,7 +65,7 @@ export { default as KanbanCallbacks } from './components/kanban/kanban.callbacks
|
|
|
64
65
|
export { KanbanColumnTop, KanbanColumnBottom } from './components/kanban/Kanban';
|
|
65
66
|
export { selectItem, activateItem, clearActiveItem, isActive, isSelected, getActive, editable, startEditing, saveCurrentEditable, selectable, handleSelect, isDeviceSmallerThan, resizeImage, refreshToolbarOperations, isOnScreenKeyboardVisible, randomString, UI, } from './utils';
|
|
66
67
|
export { getNiceStringDateTime, getFormattedStringDate, getNiceStringDate, dayName, monthName } from './components/date_utils';
|
|
67
|
-
export { mainContentPageReloader, reloadMainContentPage, reloadWholeApp, alerts, addAlert, onErrorShowAlert, main_sidebar_visible_store, tagsReloader, reloadVisibleTags } from './stores.js';
|
|
68
|
+
export { mainContentPageReloader, reloadMainContentPage, reloadWholeApp, alerts, addAlert, onErrorShowAlert, main_sidebar_visible_store, tagsReloader, reloadVisibleTags, dark_mode_store } from './stores.js';
|
|
68
69
|
export { data_tick_store, // tmp
|
|
69
70
|
hasSelectedItem, hasDataItem, setNavigatorTitle } from "./stores";
|
|
70
71
|
export { contextToolbarOperations, pageToolbarOperations, contextItemsStore, contextTypesStore } from './stores'; // tmp
|
package/operations.svelte
CHANGED
|
@@ -122,7 +122,7 @@ function isOperationActivated(operation) {
|
|
|
122
122
|
</script>
|
|
123
123
|
|
|
124
124
|
{#if hasOperations}
|
|
125
|
-
<section class="flex flex-row no-print h-10 bg-stone-
|
|
125
|
+
<section class="flex flex-row no-print h-10 bg-stone-50 dark:bg-stone-950 overflow-x-clip overflow-y-hidden py-0 text-xs whitespace-nowrap">
|
|
126
126
|
<div class="flex flex-row"
|
|
127
127
|
class:flex-row-reverse={mobile}>
|
|
128
128
|
|
|
@@ -133,9 +133,10 @@ function isOperationActivated(operation) {
|
|
|
133
133
|
{#each operation.toolbox as operation}
|
|
134
134
|
<button type="button"
|
|
135
135
|
class="py-2.5 px-4
|
|
136
|
-
text-sm font-thin
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
text-sm font-thin
|
|
137
|
+
text-stone-800 hover:bg-stone-700 active:bg-stone-300 border-stone-200
|
|
138
|
+
dark:text-stone-300 dark:hover:text-white dark:hover:bg-stone-800 dark:active:bg-stone-600 dark:border-stone-600
|
|
139
|
+
focus:outline-none
|
|
139
140
|
inline-flex items-center"
|
|
140
141
|
class:bg-stone-700={isActive}
|
|
141
142
|
class:dark:bg-stone-800={isActive}
|
|
@@ -153,9 +154,10 @@ function isOperationActivated(operation) {
|
|
|
153
154
|
|
|
154
155
|
<button type="button"
|
|
155
156
|
class="py-2.5 px-4
|
|
156
|
-
text-sm font-thin
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
text-sm font-thin
|
|
158
|
+
text-stone-600 hover:text-stone-800 hover:bg-stone-200 active:bg-stone-200 border-stone-200
|
|
159
|
+
dark:text-stone-300 dark:hover:text-white dark:hover:bg-stone-800 dark:active:bg-stone-600 dark:border-stone-600
|
|
160
|
+
focus:outline-none
|
|
159
161
|
inline-flex items-center"
|
|
160
162
|
class:bg-stone-700={isActive}
|
|
161
163
|
class:dark:bg-stone-800={isActive}
|
|
@@ -181,9 +183,10 @@ function isOperationActivated(operation) {
|
|
|
181
183
|
{@const isActive=isOperationActivated(operation)}
|
|
182
184
|
<button type="button"
|
|
183
185
|
class="py-2.5 px-4
|
|
184
|
-
text-sm font-thin
|
|
185
|
-
|
|
186
|
-
|
|
186
|
+
text-sm font-thin
|
|
187
|
+
text-stone-600 hover:text-stone-800 hover:bg-stone-200 active:bg-stone-200 border-stone-200
|
|
188
|
+
dark:text-stone-300 dark:hover:text-white dark:hover:bg-stone-800 dark:active:bg-stone-600 dark:border-stone-600
|
|
189
|
+
focus:outline-none
|
|
187
190
|
inline-flex items-center"
|
|
188
191
|
class:bg-stone-700={isActive}
|
|
189
192
|
class:dark:bg-stone-800={isActive}
|
package/package.json
CHANGED
package/tenant.members.svelte
CHANGED
package/vertical.toolbar.svelte
CHANGED
|
@@ -28,10 +28,12 @@
|
|
|
28
28
|
import { popNavigationPage } from './utils';
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
export let appConfig;
|
|
31
|
+
export let appConfig = undefined;
|
|
32
32
|
export let mobile=false;
|
|
33
33
|
export let clearsContext = 'sel props'
|
|
34
34
|
|
|
35
|
+
export let definedTabs = undefined
|
|
36
|
+
export let mainToolbarConfig = undefined
|
|
35
37
|
|
|
36
38
|
let tabs = new Array();
|
|
37
39
|
let config = null;
|
|
@@ -46,10 +48,19 @@
|
|
|
46
48
|
let can_add_new_group = false;
|
|
47
49
|
|
|
48
50
|
$: {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
if(appConfig)
|
|
52
|
+
{
|
|
53
|
+
config = appConfig.mainToolbar;
|
|
54
|
+
has_selection_details = appConfig.selectionDetails;
|
|
55
|
+
if(has_selection_details)
|
|
56
|
+
selection_detils_caption = appConfig.selectionDetails.caption ?? 'Properties'
|
|
57
|
+
}
|
|
58
|
+
else
|
|
59
|
+
{
|
|
60
|
+
has_selection_details = false;
|
|
61
|
+
config = mainToolbarConfig;
|
|
62
|
+
}
|
|
63
|
+
|
|
53
64
|
is_logged_in = $session.isActive;
|
|
54
65
|
show_sign_in_out_icons = config.signin ? true : false;
|
|
55
66
|
sign_in_href = $signInHRef;
|
|
@@ -57,23 +68,38 @@
|
|
|
57
68
|
|
|
58
69
|
tabs = new Array();
|
|
59
70
|
|
|
60
|
-
|
|
61
|
-
{
|
|
62
|
-
const ctab = appConfig.sidebar[key];
|
|
63
|
-
const can_show = (ctab.authorized && is_logged_in) || (!ctab.authorized)
|
|
64
|
-
if(can_show)
|
|
65
|
-
tabs.push({key: key, icon: ctab.icon});
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
// there is no current visible sidebar
|
|
69
|
-
if($main_sidebar_visible_store != '*')
|
|
71
|
+
if(definedTabs && Array.isArray(definedTabs) && definedTabs.length > 0)
|
|
70
72
|
{
|
|
71
|
-
|
|
73
|
+
tabs = [...definedTabs]
|
|
74
|
+
}
|
|
75
|
+
else
|
|
76
|
+
{
|
|
77
|
+
Object.keys(appConfig.sidebar).forEach( (key) =>
|
|
78
|
+
{
|
|
79
|
+
const ctab = appConfig.sidebar[key];
|
|
80
|
+
const can_show = (ctab.authorized && is_logged_in) || (!ctab.authorized)
|
|
81
|
+
if(can_show)
|
|
82
|
+
{
|
|
83
|
+
const tab = {
|
|
84
|
+
key: key,
|
|
85
|
+
icon: ctab.icon,
|
|
86
|
+
onclick: (e) => on_navigator_tab_clicked(e, key)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
tabs.push(tab);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// there is no current visible sidebar
|
|
94
|
+
if($main_sidebar_visible_store != '*')
|
|
72
95
|
{
|
|
73
|
-
if(tabs.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
96
|
+
if(tabs.every( (e) => e.key != $main_sidebar_visible_store))
|
|
97
|
+
{
|
|
98
|
+
if(tabs.length)
|
|
99
|
+
show_sidebar(tabs[0].key);
|
|
100
|
+
else
|
|
101
|
+
hide_sidebar();
|
|
102
|
+
}
|
|
77
103
|
}
|
|
78
104
|
}
|
|
79
105
|
|
|
@@ -94,9 +120,11 @@
|
|
|
94
120
|
|
|
95
121
|
}
|
|
96
122
|
|
|
97
|
-
function
|
|
123
|
+
function on_navigator_tab_clicked(e, key)
|
|
98
124
|
{
|
|
99
|
-
|
|
125
|
+
e.stopPropagation();
|
|
126
|
+
|
|
127
|
+
if(!mobile)
|
|
100
128
|
toggle_sidebar(key);
|
|
101
129
|
else
|
|
102
130
|
{
|
|
@@ -331,7 +359,7 @@
|
|
|
331
359
|
<button
|
|
332
360
|
class="h-16 px-0 flex justify-center items-center w-full text-stone-300 hover:text-stone-100"
|
|
333
361
|
class:bg-orange-500={isSelected}
|
|
334
|
-
on:click
|
|
362
|
+
on:click={tab.onclick}>
|
|
335
363
|
|
|
336
364
|
<Icon class="w-5 h-5" component={tab.icon}/>
|
|
337
365
|
</button>
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
/** @typedef {typeof __propDef.events} VerticalEvents */
|
|
3
3
|
/** @typedef {typeof __propDef.slots} VerticalSlots */
|
|
4
4
|
export default class Vertical extends SvelteComponentTyped<{
|
|
5
|
-
appConfig
|
|
5
|
+
appConfig?: any;
|
|
6
6
|
mobile?: boolean | undefined;
|
|
7
7
|
clearsContext?: string | undefined;
|
|
8
|
+
definedTabs?: any;
|
|
9
|
+
mainToolbarConfig?: any;
|
|
8
10
|
}, {
|
|
9
11
|
[evt: string]: CustomEvent<any>;
|
|
10
12
|
}, {}> {
|
|
@@ -15,9 +17,11 @@ export type VerticalSlots = typeof __propDef.slots;
|
|
|
15
17
|
import { SvelteComponentTyped } from "svelte";
|
|
16
18
|
declare const __propDef: {
|
|
17
19
|
props: {
|
|
18
|
-
appConfig
|
|
20
|
+
appConfig?: any;
|
|
19
21
|
mobile?: boolean | undefined;
|
|
20
22
|
clearsContext?: string | undefined;
|
|
23
|
+
definedTabs?: any;
|
|
24
|
+
mainToolbarConfig?: any;
|
|
21
25
|
};
|
|
22
26
|
events: {
|
|
23
27
|
[evt: string]: CustomEvent<any>;
|