@humandialog/forms.svelte 1.5.1 → 1.6.1
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/combo/combo.svelte +4 -4
- package/components/contextmenu.svelte +125 -28
- package/components/contextmenu.svelte.d.ts +2 -2
- package/components/date_utils.d.ts +3 -3
- package/components/date_utils.js +59 -56
- package/components/document/editor.svelte +46 -36
- package/components/document/editor.svelte.d.ts +6 -6
- package/components/menu.d.ts +5 -1
- package/components/menu.js +7 -3
- package/components/paginator.svelte +10 -2
- package/components/sidebar/sidebar.item.svelte +5 -5
- package/components/tags.palette.svelte +8 -3
- package/desk.svelte +10 -9
- package/horizontal.toolbar.svelte +57 -65
- package/i18n-preprocess.d.ts +39 -0
- package/i18n-preprocess.js +100 -0
- package/i18n.d.ts +32 -0
- package/i18n.js +188 -0
- package/index.d.ts +5 -3
- package/index.js +5 -3
- package/modal.svelte +2 -1
- package/package.json +3 -1
- package/stores.d.ts +1 -0
- package/stores.js +4 -3
- package/tenant.members.svelte +46 -40
- package/utils.d.ts +14 -4
- package/utils.js +178 -18
- package/vertical.toolbar.svelte +65 -42
|
@@ -25,19 +25,19 @@ declare const __propDef: {
|
|
|
25
25
|
run?: ((onStop?: undefined) => void) | undefined;
|
|
26
26
|
getFormattingOperations?: ((withCaptions?: boolean) => any[]) | undefined;
|
|
27
27
|
getMarksOperations?: ((tbr?: string) => {
|
|
28
|
-
caption:
|
|
28
|
+
caption: any;
|
|
29
29
|
operations: any[];
|
|
30
30
|
preAction: (f: any) => void;
|
|
31
31
|
tbr: string;
|
|
32
32
|
}) | undefined;
|
|
33
33
|
getStylesOperations?: ((tbr?: string) => {
|
|
34
|
-
caption:
|
|
34
|
+
caption: any;
|
|
35
35
|
operations: any[];
|
|
36
36
|
preAction: (f: any) => void;
|
|
37
37
|
tbr: string;
|
|
38
38
|
}) | undefined;
|
|
39
39
|
getInsertOperations?: ((tbr?: string) => {
|
|
40
|
-
caption:
|
|
40
|
+
caption: any;
|
|
41
41
|
operations: any[];
|
|
42
42
|
preAction: (f: any) => void;
|
|
43
43
|
tbr: string;
|
|
@@ -98,19 +98,19 @@ export default class Editor extends SvelteComponentTyped<EditorProps, EditorEven
|
|
|
98
98
|
get run(): (onStop?: undefined) => void;
|
|
99
99
|
get getFormattingOperations(): (withCaptions?: boolean) => any[];
|
|
100
100
|
get getMarksOperations(): (tbr?: string) => {
|
|
101
|
-
caption:
|
|
101
|
+
caption: any;
|
|
102
102
|
operations: any[];
|
|
103
103
|
preAction: (f: any) => void;
|
|
104
104
|
tbr: string;
|
|
105
105
|
};
|
|
106
106
|
get getStylesOperations(): (tbr?: string) => {
|
|
107
|
-
caption:
|
|
107
|
+
caption: any;
|
|
108
108
|
operations: any[];
|
|
109
109
|
preAction: (f: any) => void;
|
|
110
110
|
tbr: string;
|
|
111
111
|
};
|
|
112
112
|
get getInsertOperations(): (tbr?: string) => {
|
|
113
|
-
caption:
|
|
113
|
+
caption: any;
|
|
114
114
|
operations: any[];
|
|
115
115
|
preAction: (f: any) => void;
|
|
116
116
|
tbr: string;
|
package/components/menu.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import Floating_container from './Floating_container.svelte';
|
|
2
|
-
export declare
|
|
2
|
+
export declare const SHOW_MENU_BELOW = 0;
|
|
3
|
+
export declare const SHOW_MENU_ABOVE = 1;
|
|
4
|
+
export declare const SHOW_MENU_RIGHT = 2;
|
|
5
|
+
export declare const SHOW_MENU_LEFT = 3;
|
|
6
|
+
export declare function showMenu(around: DOMRect | DOMPoint, operations: any, preference?: number): void;
|
|
3
7
|
export declare function hideWholeContextMenu(): void;
|
|
4
8
|
export declare function showFloatingToolbar(around: DOMRect | DOMPoint, toolbar: any, props?: {}): Floating_container | null;
|
|
5
9
|
export declare function hideFloatingToolbar(): void;
|
package/components/menu.js
CHANGED
|
@@ -3,7 +3,11 @@ import Floating_container from './Floating_container.svelte';
|
|
|
3
3
|
import Grid from './Grid.menu.svelte';
|
|
4
4
|
let menu_comopnent = null;
|
|
5
5
|
let toolbar_component = null;
|
|
6
|
-
export
|
|
6
|
+
export const SHOW_MENU_BELOW = 0;
|
|
7
|
+
export const SHOW_MENU_ABOVE = 1;
|
|
8
|
+
export const SHOW_MENU_RIGHT = 2;
|
|
9
|
+
export const SHOW_MENU_LEFT = 3;
|
|
10
|
+
export function showMenu(around, operations, preference = SHOW_MENU_BELOW) {
|
|
7
11
|
let menu_element = document.getElementById("__hd_svelte_contextmenu");
|
|
8
12
|
if (!menu_element) {
|
|
9
13
|
let app_div = document.getElementById("__hd_svelte_layout_root");
|
|
@@ -13,13 +17,13 @@ export function showMenu(around, operations) {
|
|
|
13
17
|
target: app_div,
|
|
14
18
|
props: {}
|
|
15
19
|
});
|
|
16
|
-
menu_comopnent.show(around, operations);
|
|
20
|
+
menu_comopnent.show(around, operations, preference);
|
|
17
21
|
}
|
|
18
22
|
else if (menu_comopnent) {
|
|
19
23
|
if (menu_comopnent.isVisible())
|
|
20
24
|
menu_comopnent.hide();
|
|
21
25
|
else
|
|
22
|
-
menu_comopnent.show(around, operations);
|
|
26
|
+
menu_comopnent.show(around, operations, preference);
|
|
23
27
|
}
|
|
24
28
|
else
|
|
25
29
|
console.error('what now?');
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
|
|
3
|
+
import {i18n} from '../i18n.js'
|
|
4
|
+
|
|
3
5
|
export let pageNo
|
|
4
6
|
export let allPagesNo
|
|
5
7
|
export let onPage
|
|
@@ -67,7 +69,9 @@
|
|
|
67
69
|
<li>
|
|
68
70
|
<button on:click={onPrevPage}
|
|
69
71
|
class="flex items-center justify-center px-3 h-8 ms-0 leading-tight text-stone-500 bg-white border border-e-0 border-stone-300 rounded-s-lg hover:bg-stone-100 hover:text-stone-700 dark:bg-stone-800 dark:border-stone-700 dark:text-stone-400 dark:hover:bg-stone-700 dark:hover:text-white">
|
|
70
|
-
<span class="sr-only">
|
|
72
|
+
<span class="sr-only">
|
|
73
|
+
{ i18n({en: 'Previous', es: 'Anterior', pl: 'Wcześniejsze'}) }
|
|
74
|
+
</span>
|
|
71
75
|
<svg class="w-2.5 h-2.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
|
|
72
76
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 1 1 5l4 4"/>
|
|
73
77
|
</svg>
|
|
@@ -94,7 +98,11 @@
|
|
|
94
98
|
<!--a href="#" aria-current="page" class="">3</a-->
|
|
95
99
|
<li>
|
|
96
100
|
<button on:click={onNextPage} class="flex items-center justify-center px-3 h-8 leading-tight text-stone-500 bg-white border border-stone-300 rounded-e-lg hover:bg-stone-100 hover:text-stone-700 dark:bg-stone-800 dark:border-stone-700 dark:text-stone-400 dark:hover:bg-stone-700 dark:hover:text-white">
|
|
97
|
-
<span class="sr-only">
|
|
101
|
+
<span class="sr-only">
|
|
102
|
+
|
|
103
|
+
{ i18n({en: 'Next', es: 'Siguiente', pl: 'Następne'}) }
|
|
104
|
+
|
|
105
|
+
</span>
|
|
98
106
|
<svg class="w-2.5 h-2.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
|
|
99
107
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4"/>
|
|
100
108
|
</svg>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script>import { getContext, tick } from "svelte";
|
|
2
2
|
import Icon from "../icon.svelte";
|
|
3
|
-
import { contextItemsStore,
|
|
3
|
+
import { contextItemsStore, contextToolbarOperations } from "../../stores";
|
|
4
4
|
import { FaBars, FaEllipsisV } from "svelte-icons/fa";
|
|
5
5
|
import { link, push } from "svelte-spa-router";
|
|
6
|
+
import { i18n } from "../../i18n";
|
|
6
7
|
import {
|
|
7
8
|
selectable as _selectable,
|
|
8
9
|
isSelected,
|
|
@@ -11,8 +12,7 @@ import {
|
|
|
11
12
|
activateItem,
|
|
12
13
|
startEditing,
|
|
13
14
|
getActive,
|
|
14
|
-
|
|
15
|
-
UI
|
|
15
|
+
navAutoHide
|
|
16
16
|
} from "../../utils";
|
|
17
17
|
import { showMenu } from "../menu";
|
|
18
18
|
export let href;
|
|
@@ -126,7 +126,7 @@ function on_link_clicked(e) {
|
|
|
126
126
|
redirect_to(href2);
|
|
127
127
|
}
|
|
128
128
|
} else {
|
|
129
|
-
|
|
129
|
+
navAutoHide();
|
|
130
130
|
redirect_to(href2);
|
|
131
131
|
}
|
|
132
132
|
}
|
|
@@ -185,7 +185,7 @@ function activateRow(e) {
|
|
|
185
185
|
opver: 1,
|
|
186
186
|
operations: [
|
|
187
187
|
{
|
|
188
|
-
caption: "View",
|
|
188
|
+
caption: i18n({ en: "View", es: "Ver", pl: "Widok" }),
|
|
189
189
|
operations: [
|
|
190
190
|
{
|
|
191
191
|
icon: FaEllipsisV,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import TagColorsPalette from './tag.colors.svelte'
|
|
5
5
|
import { tick } from 'svelte';
|
|
6
6
|
import { isDeviceSmallerThan } from '../utils';
|
|
7
|
+
import {i18n} from '../i18n'
|
|
7
8
|
|
|
8
9
|
export let usedTags = []
|
|
9
10
|
export let allTags = []
|
|
@@ -194,9 +195,13 @@
|
|
|
194
195
|
onCustomClick={(e) => onTagSelected(tag)}/>
|
|
195
196
|
{/each}
|
|
196
197
|
{:else if allowNewTags}
|
|
197
|
-
<p>
|
|
198
|
+
<p>
|
|
199
|
+
{ i18n({en: 'Create tag:', es: 'Crear etiqueta:', pl: 'Utwrórz etykietę:'}) }
|
|
200
|
+
</p>
|
|
198
201
|
{:else}
|
|
199
|
-
<p>
|
|
202
|
+
<p>
|
|
203
|
+
{ i18n({en: 'No tags', es: 'Sin etiquetas', pl: 'Żadnych etykiet'}) }
|
|
204
|
+
</p>
|
|
200
205
|
{/if}
|
|
201
206
|
|
|
202
207
|
{/key}
|
|
@@ -211,7 +216,7 @@
|
|
|
211
216
|
on:input={onTextInput}
|
|
212
217
|
on:blur={onTextBlur}
|
|
213
218
|
on:keydown={onKeyDown}
|
|
214
|
-
placeholder=
|
|
219
|
+
placeholder={i18n({en: 'Type to filter or create tag', es: 'Escriba para filtrar o crear una etiqueta', pl: 'Wpisz, aby filtrować lub utworzyć tag'})}>
|
|
215
220
|
{#if allowNewTags}
|
|
216
221
|
<button class="block w-5 h-5 mt-0.5 ml-auto mr-2
|
|
217
222
|
text-stone-600 hover:text-stone-800 hover:bg-stone-200 active:bg-stone-200 border-stone-200
|
package/desk.svelte
CHANGED
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
import {main_sidebar_visible_store,
|
|
10
10
|
tools_visible_store,
|
|
11
11
|
bottom_bar_visible_store,
|
|
12
|
-
auto_hide_sidebar,
|
|
13
12
|
hasSelectedItem,
|
|
14
13
|
dark_mode_store,
|
|
15
14
|
data_tick_store,
|
|
@@ -20,7 +19,7 @@
|
|
|
20
19
|
alerts, removeAlert, showFABAlways} from './stores.js'
|
|
21
20
|
|
|
22
21
|
//import { AuthorizedView} from '@humandialog/auth.svelte'
|
|
23
|
-
import { handleSelect, isDeviceSmallerThan,
|
|
22
|
+
import { handleSelect, isDeviceSmallerThan, isOnScreenKeyboardVisible, navGetMode, removeAt, UI, NAV_MODE_SIDEBAR, navAutoHide, navIsVisible } from './utils'
|
|
24
23
|
import { afterUpdate, onMount } from 'svelte';
|
|
25
24
|
import {location} from 'svelte-spa-router'
|
|
26
25
|
import {FaCopy, FaTimes} from 'svelte-icons/fa'
|
|
@@ -76,8 +75,8 @@
|
|
|
76
75
|
//let autoRedirectToSignIn = layout.autoRedirectToSignIn ?? true
|
|
77
76
|
|
|
78
77
|
$: { visible_sidebar = $main_sidebar_visible_store
|
|
79
|
-
|
|
80
|
-
if(
|
|
78
|
+
const navMode = navGetMode()
|
|
79
|
+
if(navMode == NAV_MODE_SIDEBAR)
|
|
81
80
|
{
|
|
82
81
|
if(visible_sidebar == "*")
|
|
83
82
|
{
|
|
@@ -190,10 +189,11 @@
|
|
|
190
189
|
}
|
|
191
190
|
|
|
192
191
|
|
|
193
|
-
$:
|
|
192
|
+
$: navigationPageSetup($location);
|
|
194
193
|
function navigationPageSetup(...args)
|
|
195
194
|
{
|
|
196
|
-
|
|
195
|
+
const navMode = navGetMode()
|
|
196
|
+
if(navMode == NAV_MODE_SIDEBAR)
|
|
197
197
|
{
|
|
198
198
|
vertical_toolbar_visibility = "hidden sm:block"
|
|
199
199
|
content_left = "left-0 sm:left-[40px]";
|
|
@@ -202,7 +202,7 @@
|
|
|
202
202
|
}
|
|
203
203
|
else
|
|
204
204
|
{
|
|
205
|
-
if(
|
|
205
|
+
if(navIsVisible())
|
|
206
206
|
{
|
|
207
207
|
vertical_toolbar_visibility = "block"
|
|
208
208
|
content_left = "left-[50px]";
|
|
@@ -254,7 +254,7 @@
|
|
|
254
254
|
|
|
255
255
|
function on_resize()
|
|
256
256
|
{
|
|
257
|
-
|
|
257
|
+
navAutoHide()
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
let minViewportHeight = 0;
|
|
@@ -278,6 +278,7 @@
|
|
|
278
278
|
|
|
279
279
|
function onViewportResize(e)
|
|
280
280
|
{
|
|
281
|
+
console.log('onViewportResize')
|
|
281
282
|
const vp = window.visualViewport;
|
|
282
283
|
setViewportHeight(vp)
|
|
283
284
|
|
|
@@ -411,7 +412,7 @@
|
|
|
411
412
|
behaviour is the content expand vertically, and only vertical scrollbar can be visible.
|
|
412
413
|
When content on the main page needs to be expanded horizontally (like kanban chart for example) then
|
|
413
414
|
that component should define overflow-x-* itself -->
|
|
414
|
-
<section on:click|capture={() =>
|
|
415
|
+
<section on:click|capture={() => navAutoHide() } class="">
|
|
415
416
|
|
|
416
417
|
<!--###########################################################-->
|
|
417
418
|
<!--## HORIZONTAL TOOLS ######################-->
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import {FaUsers, FaCog, FaSignInAlt, FaSignOutAlt, FaBars, FaToggleOn, FaToggleOff} from 'svelte-icons/fa/'
|
|
2
|
+
import {FaUsers, FaCog, FaSignInAlt, FaSignOutAlt, FaBars, FaToggleOn, FaToggleOff, FaLanguage} from 'svelte-icons/fa/'
|
|
3
3
|
//import GoPrimitiveDot from 'svelte-icons/go/GoPrimitiveDot.svelte'
|
|
4
4
|
import {showMenu} from './components/menu'
|
|
5
5
|
import {push, pop, location} from 'svelte-spa-router'
|
|
@@ -8,13 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
10
|
dark_mode_store,
|
|
11
|
-
toggle_sidebar,
|
|
12
|
-
show_sidebar,
|
|
13
|
-
hide_sidebar,
|
|
14
11
|
tools_visible_store,
|
|
15
12
|
bottom_bar_visible_store,
|
|
16
|
-
previously_visible_sidebar,
|
|
17
|
-
main_sidebar_visible_store,
|
|
18
13
|
sidebar_left_pos,
|
|
19
14
|
page_title,
|
|
20
15
|
nav_titles,
|
|
@@ -24,8 +19,8 @@
|
|
|
24
19
|
import {session, signInHRef, signOutHRef} from '@humandialog/auth.svelte'
|
|
25
20
|
|
|
26
21
|
import VerticalToolbar from './vertical.toolbar.svelte'
|
|
27
|
-
import { isDeviceSmallerThan,
|
|
28
|
-
|
|
22
|
+
import { isDeviceSmallerThan, navIsVisible, navGetKey, navToggle, navShow, navHide, navPrevVisibleKey } from './utils.js';
|
|
23
|
+
import {setCurrentLanguage, getLanguages, i18n, getCurrentLanguage} from './i18n.js'
|
|
29
24
|
|
|
30
25
|
export let appConfig = undefined;
|
|
31
26
|
export let clearsContext = 'sel props'
|
|
@@ -35,7 +30,7 @@
|
|
|
35
30
|
|
|
36
31
|
let config = null;
|
|
37
32
|
let has_selection_details = false;
|
|
38
|
-
let selection_details_caption = 'Properties'
|
|
33
|
+
let selection_details_caption = i18n({en: 'Properties', es: 'Propiedades', pl: 'Właściwości'});
|
|
39
34
|
|
|
40
35
|
let show_sign_in_out_icons = false;
|
|
41
36
|
let is_logged_in = false;
|
|
@@ -53,7 +48,13 @@
|
|
|
53
48
|
config = appConfig.mainToolbar;
|
|
54
49
|
has_selection_details = appConfig.selectionDetails;
|
|
55
50
|
if(has_selection_details)
|
|
56
|
-
|
|
51
|
+
{
|
|
52
|
+
if(appConfig.selectionDetails.captionFunc)
|
|
53
|
+
selection_details_caption = appConfig.selectionDetails.captionFunc()
|
|
54
|
+
else if(appConfig.selectionDetails.caption)
|
|
55
|
+
selection_details_caption = appConfig.selectionDetails.caption
|
|
56
|
+
|
|
57
|
+
}
|
|
57
58
|
}
|
|
58
59
|
else
|
|
59
60
|
{
|
|
@@ -86,11 +87,12 @@
|
|
|
86
87
|
|
|
87
88
|
let title = ''
|
|
88
89
|
$:{
|
|
89
|
-
if(
|
|
90
|
+
if(!navIsVisible())
|
|
90
91
|
title = $page_title;
|
|
91
92
|
else
|
|
92
93
|
{
|
|
93
|
-
|
|
94
|
+
const navKey = navGetKey()
|
|
95
|
+
let nav_title = $nav_titles[navKey];
|
|
94
96
|
if(nav_title != undefined)
|
|
95
97
|
title = nav_title
|
|
96
98
|
else
|
|
@@ -100,59 +102,25 @@
|
|
|
100
102
|
|
|
101
103
|
function toggle_navigator(e)
|
|
102
104
|
{
|
|
103
|
-
if(
|
|
105
|
+
if(tabs.length == 1)
|
|
104
106
|
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
popNavigationPage();
|
|
108
|
-
}
|
|
109
|
-
else
|
|
110
|
-
{
|
|
111
|
-
if(tabs.length == 1)
|
|
112
|
-
{
|
|
113
|
-
$sidebar_left_pos = 0;
|
|
114
|
-
show_sidebar(tabs[0]);
|
|
115
|
-
}
|
|
116
|
-
else
|
|
117
|
-
{
|
|
118
|
-
let sidebar = $main_sidebar_visible_store;
|
|
119
|
-
if(sidebar == "*")
|
|
120
|
-
{
|
|
121
|
-
if((!previously_visible_sidebar) || previously_visible_sidebar === '*')
|
|
122
|
-
sidebar = Object.keys(appConfig.sidebar)[0];
|
|
123
|
-
else
|
|
124
|
-
sidebar = previously_visible_sidebar;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
$sidebar_left_pos = 40;
|
|
128
|
-
show_sidebar(sidebar)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
pushNavigationPage();
|
|
132
|
-
}
|
|
107
|
+
$sidebar_left_pos = 0;
|
|
108
|
+
navToggle(tabs[0])
|
|
133
109
|
}
|
|
134
110
|
else
|
|
135
111
|
{
|
|
112
|
+
$sidebar_left_pos = 40;
|
|
136
113
|
|
|
137
|
-
if(
|
|
114
|
+
if(!navIsVisible())
|
|
138
115
|
{
|
|
139
|
-
|
|
140
|
-
|
|
116
|
+
let navKey = navPrevVisibleKey()
|
|
117
|
+
if(!navKey)
|
|
118
|
+
navKey = Object.keys(appConfig.sidebar)[0]
|
|
119
|
+
|
|
120
|
+
navShow(navKey);
|
|
141
121
|
}
|
|
142
122
|
else
|
|
143
|
-
|
|
144
|
-
let sidebar = $main_sidebar_visible_store;
|
|
145
|
-
if(sidebar == "*")
|
|
146
|
-
{
|
|
147
|
-
if((!previously_visible_sidebar) || previously_visible_sidebar === '*')
|
|
148
|
-
sidebar = Object.keys(appConfig.sidebar)[0];
|
|
149
|
-
else
|
|
150
|
-
sidebar = previously_visible_sidebar;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
$sidebar_left_pos = 40;
|
|
154
|
-
toggle_sidebar(sidebar)
|
|
155
|
-
}
|
|
123
|
+
navHide()
|
|
156
124
|
}
|
|
157
125
|
}
|
|
158
126
|
|
|
@@ -177,8 +145,14 @@
|
|
|
177
145
|
|
|
178
146
|
if(add)
|
|
179
147
|
{
|
|
148
|
+
let caption = ''
|
|
149
|
+
if(o.captionFunc)
|
|
150
|
+
caption = o.captionFunc()
|
|
151
|
+
else if(o.caption)
|
|
152
|
+
caption = o.caption
|
|
153
|
+
|
|
180
154
|
options.push({
|
|
181
|
-
caption:
|
|
155
|
+
caption: caption,
|
|
182
156
|
icon: o.icon,
|
|
183
157
|
action: o.action
|
|
184
158
|
})
|
|
@@ -191,7 +165,7 @@
|
|
|
191
165
|
if(!is_logged_in)
|
|
192
166
|
{
|
|
193
167
|
options.push({
|
|
194
|
-
caption: 'Sign in',
|
|
168
|
+
caption: i18n( { en: 'Sign in', es: 'Iniciar sesión', pl: 'Zaloguj'}),
|
|
195
169
|
icon: FaSignInAlt,
|
|
196
170
|
action: (focused) => { push(sign_in_href) }
|
|
197
171
|
});
|
|
@@ -199,7 +173,7 @@
|
|
|
199
173
|
else
|
|
200
174
|
{
|
|
201
175
|
options.push({
|
|
202
|
-
caption: 'Sign out',
|
|
176
|
+
caption: i18n({en: 'Sign out', es: 'Cerrar sesión', pl: 'Wyloguj' }) ,
|
|
203
177
|
icon: FaSignOutAlt,
|
|
204
178
|
action: (focused) => { push(sign_out_href) }
|
|
205
179
|
});
|
|
@@ -211,10 +185,11 @@
|
|
|
211
185
|
|
|
212
186
|
if(!config || config.darkMode)
|
|
213
187
|
{
|
|
188
|
+
const capt = i18n({en: 'Dark mode', es: 'Modo oscuro', pl: 'Tryb ciemny'})
|
|
214
189
|
if($dark_mode_store == '')
|
|
215
190
|
{
|
|
216
191
|
options.push( {
|
|
217
|
-
caption:
|
|
192
|
+
caption: capt,
|
|
218
193
|
icon: FaToggleOff,
|
|
219
194
|
action: (focused) => { $dark_mode_store = 'dark'; }
|
|
220
195
|
});
|
|
@@ -222,24 +197,41 @@
|
|
|
222
197
|
else
|
|
223
198
|
{
|
|
224
199
|
options.push( {
|
|
225
|
-
caption:
|
|
200
|
+
caption: capt,
|
|
226
201
|
icon: FaToggleOn,
|
|
227
202
|
action: (focused) => { $dark_mode_store = ''; }
|
|
228
203
|
});
|
|
229
204
|
}
|
|
230
205
|
}
|
|
231
206
|
|
|
207
|
+
const langs = getLanguages()
|
|
208
|
+
if(langs && langs.length > 1)
|
|
209
|
+
{
|
|
210
|
+
const langMenu = langs.map( l => ({
|
|
211
|
+
caption: l.name,
|
|
212
|
+
img: l.flag,
|
|
213
|
+
action: (b) => {setCurrentLanguage(l); reloadWholeApp()},
|
|
214
|
+
disabled: getCurrentLanguage() == l
|
|
215
|
+
}))
|
|
216
|
+
|
|
217
|
+
options.push( {
|
|
218
|
+
caption: i18n({en: 'Language', es:'Idioma', pl:'Język'}),
|
|
219
|
+
menu: langMenu,
|
|
220
|
+
icon: FaLanguage
|
|
221
|
+
})
|
|
222
|
+
}
|
|
223
|
+
|
|
232
224
|
if(config && config.operations)
|
|
233
225
|
{
|
|
234
226
|
options.push( {
|
|
235
|
-
caption: 'Toolbar',
|
|
227
|
+
caption: i18n({en:'Toolbar', es:'Barra de herramientas', pl:'Pasek narzędzi'}),
|
|
236
228
|
icon: $tools_visible_store ? FaToggleOn : FaToggleOff,
|
|
237
229
|
action: (focused) => { $tools_visible_store = !$tools_visible_store; }
|
|
238
230
|
});
|
|
239
231
|
}
|
|
240
232
|
|
|
241
233
|
options.push({
|
|
242
|
-
caption: 'Left-handed
|
|
234
|
+
caption: i18n({en: 'Left-handed mode', es: 'Modo para zurdos', pl: 'Tryb dla leworęcznych'}),
|
|
243
235
|
icon: $leftHandedFAB ? FaToggleOn : FaToggleOff,
|
|
244
236
|
action: (f) => { $leftHandedFAB = !$leftHandedFAB; }
|
|
245
237
|
})
|
|
@@ -344,7 +336,7 @@
|
|
|
344
336
|
|
|
345
337
|
</div>
|
|
346
338
|
|
|
347
|
-
{#if false && tabs.length > 1 &&
|
|
339
|
+
{#if false && tabs.length > 1 && navIsVisible()}
|
|
348
340
|
<div class="no-print flex-none block fixed left-0 top-[40px] w-[40px] h-screen z-20 inset-0 overflow-hidden">
|
|
349
341
|
<div class="sticky top-0 flex h-full w-10 bg-stone-900 flex-col items-center text-stone-100 shadow">
|
|
350
342
|
<VerticalToolbar {appConfig} mobile={true}/>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zamienia:
|
|
3
|
+
* _; EN;ES ; PL
|
|
4
|
+
* "_; EN;ES ; PL"
|
|
5
|
+
* '_; Foo ; Bar;Baz'
|
|
6
|
+
* `_; A; B ; C`
|
|
7
|
+
* na:
|
|
8
|
+
* i18n(["EN", "ES", "PL"]) // znormalizowane odstępy: "; "
|
|
9
|
+
*
|
|
10
|
+
* Dwie fazy:
|
|
11
|
+
* 1) quoted: podmienia CAŁE literały stringów (", ', `)
|
|
12
|
+
* 2) unquoted: podmienia goły tekst (np. w markupie)
|
|
13
|
+
*/
|
|
14
|
+
export function i18nPreprocess({ dryRun }?: {
|
|
15
|
+
dryRun?: boolean | undefined;
|
|
16
|
+
}): {
|
|
17
|
+
name: string;
|
|
18
|
+
markup({ content, filename }: {
|
|
19
|
+
content: any;
|
|
20
|
+
filename: any;
|
|
21
|
+
}): {
|
|
22
|
+
code: any;
|
|
23
|
+
};
|
|
24
|
+
script({ content, attributes, filename }: {
|
|
25
|
+
content: any;
|
|
26
|
+
attributes: any;
|
|
27
|
+
filename: any;
|
|
28
|
+
}): {
|
|
29
|
+
code: any;
|
|
30
|
+
attributes: any;
|
|
31
|
+
};
|
|
32
|
+
style({ content, attributes }: {
|
|
33
|
+
content: any;
|
|
34
|
+
attributes: any;
|
|
35
|
+
}): {
|
|
36
|
+
code: any;
|
|
37
|
+
attributes: any;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zamienia:
|
|
3
|
+
* _; EN;ES ; PL
|
|
4
|
+
* "_; EN;ES ; PL"
|
|
5
|
+
* '_; Foo ; Bar;Baz'
|
|
6
|
+
* `_; A; B ; C`
|
|
7
|
+
* na:
|
|
8
|
+
* i18n(["EN", "ES", "PL"]) // znormalizowane odstępy: "; "
|
|
9
|
+
*
|
|
10
|
+
* Dwie fazy:
|
|
11
|
+
* 1) quoted: podmienia CAŁE literały stringów (", ', `)
|
|
12
|
+
* 2) unquoted: podmienia goły tekst (np. w markupie)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export function i18nPreprocess({ dryRun = false } = {}) {
|
|
16
|
+
const lit = (s) => JSON.stringify(s);
|
|
17
|
+
const toArrayExpr = (list) =>
|
|
18
|
+
`[${list
|
|
19
|
+
.split(/\s*;\s*/g) // zachowuje puste między ';;'
|
|
20
|
+
.map((s) => s.trim()) // przytnij brzegi
|
|
21
|
+
.map(lit) // JSON.stringify
|
|
22
|
+
.join(', ')}]`;
|
|
23
|
+
|
|
24
|
+
// 1) W <script> zamieniamy CAŁE literały "_; ...; ..." -> i18n([ ... ])
|
|
25
|
+
// Uwaga: dla prostoty nie dopuszczamy cudzysłowów/backticków wewnątrz placeholderów
|
|
26
|
+
const QUOTED_IN_SCRIPT =
|
|
27
|
+
/(['"`])\s*_;\s*((?:[^'"`;\r\n]*)(?:\s*;\s*[^'"`;\r\n]*)*)\s*\1/g;
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
// 2) W markup – TYLKO surowy tekst między tagami (nie dotykamy atrybutów)
|
|
31
|
+
const UNQUOTED_TEXT_IN_MARKUP =
|
|
32
|
+
/(^|>)(\s*)_;\s*((?:[^;<>]*)(?:\s*;\s*[^;<>]*)*)/g;
|
|
33
|
+
|
|
34
|
+
// ATRYBUTY: name="_; A; ; C" -> name={i18n(["A", "", "C"])}
|
|
35
|
+
const ATTR_QUOTED =
|
|
36
|
+
/(\s[0-9A-Za-z_:@#.-]+)\s*=\s*(["'])\s*_;\s*((?:[^"'<>]*)(?:\s*;\s*[^"'<>]*)*)\s*\2/g;
|
|
37
|
+
|
|
38
|
+
// Wytnij i przywróć bloki, żeby w fazie markup nie ruszać <script>/<style>
|
|
39
|
+
const extractBlocks = (content, tag) => {
|
|
40
|
+
const re = new RegExp(`<${tag}\\b[\\s\\S]*?>[\\s\\S]*?<\\/${tag}>`, 'gi');
|
|
41
|
+
const blocks = [];
|
|
42
|
+
const placeholders = [];
|
|
43
|
+
let i = 0;
|
|
44
|
+
content = content.replace(re, (m) => {
|
|
45
|
+
const key = `<<<${tag.toUpperCase()}_BLOCK_${i++}>>>`;
|
|
46
|
+
blocks.push(m);
|
|
47
|
+
placeholders.push(key);
|
|
48
|
+
return key;
|
|
49
|
+
});
|
|
50
|
+
return { content, blocks, placeholders };
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// UWAGA: używamy funkcji jako replacera, by nie zepsuć `$$props` -> `$props`
|
|
54
|
+
const restoreBlocks = (content, placeholders, blocks) => {
|
|
55
|
+
placeholders.forEach((key, idx) => {
|
|
56
|
+
content = content.replace(key, () => blocks[idx]);
|
|
57
|
+
});
|
|
58
|
+
return content;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
name: 'i18n-preprocess',
|
|
63
|
+
|
|
64
|
+
markup({ content, filename }) {
|
|
65
|
+
const s = extractBlocks(content, 'script');
|
|
66
|
+
const ss = extractBlocks(s.content, 'style');
|
|
67
|
+
|
|
68
|
+
let body = ss.content;
|
|
69
|
+
let count = 0;
|
|
70
|
+
|
|
71
|
+
body = body.replace(UNQUOTED_TEXT_IN_MARKUP, (m, before, pre, list) => {
|
|
72
|
+
count++;
|
|
73
|
+
return `${before}${pre}{i18n(${toArrayExpr(list)})}`;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
if (count) console.log(`[i18n-preprocess][markup] ${filename} -> ${count} replace(s)`);
|
|
77
|
+
|
|
78
|
+
body = restoreBlocks(body, ss.placeholders, ss.blocks);
|
|
79
|
+
body = restoreBlocks(body, s.placeholders, s.blocks);
|
|
80
|
+
|
|
81
|
+
if (dryRun) return { code: content };
|
|
82
|
+
return { code: body };
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
script({ content, attributes, filename }) {
|
|
86
|
+
let count = 0;
|
|
87
|
+
const code = content.replace(QUOTED_IN_SCRIPT, (_m, _q, list) => {
|
|
88
|
+
count++;
|
|
89
|
+
return `i18n(${toArrayExpr(list)})`;
|
|
90
|
+
});
|
|
91
|
+
// if (count) console.log(`[i18n-preprocess][script] ${filename} -> ${count} replace(s)`);
|
|
92
|
+
if (dryRun) return { code: content, attributes };
|
|
93
|
+
return { code, attributes };
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
style({ content, attributes }) {
|
|
97
|
+
return { code: content, attributes };
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
package/i18n.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function setLanguages(langs: any): void;
|
|
2
|
+
export function getLanguages(): ({
|
|
3
|
+
key: string;
|
|
4
|
+
name: string;
|
|
5
|
+
flag: string;
|
|
6
|
+
default: boolean;
|
|
7
|
+
} | {
|
|
8
|
+
key: string;
|
|
9
|
+
name: string;
|
|
10
|
+
flag: string;
|
|
11
|
+
default?: undefined;
|
|
12
|
+
})[];
|
|
13
|
+
export function setCurrentLanguage(sel: any): void;
|
|
14
|
+
export function getCurrentLanguage(): {
|
|
15
|
+
key: string;
|
|
16
|
+
name: string;
|
|
17
|
+
flag: string;
|
|
18
|
+
default: boolean;
|
|
19
|
+
} | {
|
|
20
|
+
key: string;
|
|
21
|
+
name: string;
|
|
22
|
+
flag: string;
|
|
23
|
+
default?: undefined;
|
|
24
|
+
};
|
|
25
|
+
export function getCurrentLanguageIdx(): number;
|
|
26
|
+
export function getCurrentLanguageKey(): string;
|
|
27
|
+
/**
|
|
28
|
+
* i18n("EN; ES; PL") => "EN" albo "ES" albo "PL"
|
|
29
|
+
*/
|
|
30
|
+
export function i18n(list: any): any;
|
|
31
|
+
export function extractTranslated(str: any): any;
|
|
32
|
+
export function ext(str: any): any;
|