@optionfactory/ful 5.0.2 → 5.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ful.css +1 -1
- package/dist/ful.css.map +1 -1
- package/dist/ful.iife.js +93 -37
- package/dist/ful.iife.js.map +1 -1
- package/dist/ful.iife.min.js +1 -1
- package/dist/ful.iife.min.js.map +1 -1
- package/dist/ful.min.mjs +1 -1
- package/dist/ful.min.mjs.map +1 -1
- package/dist/ful.mjs +93 -37
- package/dist/ful.mjs.map +1 -1
- package/package.json +1 -1
package/dist/ful.mjs
CHANGED
|
@@ -1688,16 +1688,18 @@ class InputFile extends Input {
|
|
|
1688
1688
|
'dropzonelabel': 'Click or drop your files here',
|
|
1689
1689
|
'unaccepptablefiletype': "Only files of type {0} are supported",
|
|
1690
1690
|
'maxfilesizeexceeded': "Maximum supported file size is {0}",
|
|
1691
|
-
'maxtotalsizeexceeded': "Maximum supported total file size is {0}"
|
|
1691
|
+
'maxtotalsizeexceeded': "Maximum supported total file size is {0}",
|
|
1692
|
+
'maxfilesexceeded': "Maximum files count exceeded"
|
|
1692
1693
|
},
|
|
1693
1694
|
it: {
|
|
1694
1695
|
'dropzonelabel': 'Clicca o trascina i file qui',
|
|
1695
1696
|
'unaccepptablefiletype': "Solo i file di tipo {0} sono supportati",
|
|
1696
1697
|
'maxfilesizeexceeded': "La dimensione massima di un file è di {0}",
|
|
1697
|
-
'maxtotalsizeexceeded': "La dimensione massima complessiva dei file è di {0}"
|
|
1698
|
+
'maxtotalsizeexceeded': "La dimensione massima complessiva dei file è di {0}",
|
|
1699
|
+
'maxfilesexceeded': "Numero massimo di file superato",
|
|
1698
1700
|
}
|
|
1699
1701
|
}
|
|
1700
|
-
static observed = ['value', 'readonly:presence', 'required:presence', "accept:csv", 'multiple:presence', "itemlist:presence", "dropzone:presence", "maxfilesize:number", "maxtotalsize:number"];
|
|
1702
|
+
static observed = ['value', 'readonly:presence', 'required:presence', "accept:csv", 'multiple:presence', "itemlist:presence", "dropzone:presence", "maxfiles:number", "maxfilesize:number", "maxtotalsize:number"];
|
|
1701
1703
|
#accept;
|
|
1702
1704
|
#items;
|
|
1703
1705
|
#dropzone;
|
|
@@ -1720,7 +1722,7 @@ class InputFile extends Input {
|
|
|
1720
1722
|
<div data-ref="dropzone" class="dropzone" data-tpl-if="slots.dropzone">
|
|
1721
1723
|
{{{{ slots.dropzone }}}}
|
|
1722
1724
|
</div>
|
|
1723
|
-
<div data-ref="dropzone" class="dropzone" data-tpl-if="!slots.dropzone">
|
|
1725
|
+
<div data-ref="dropzone" class="default-dropzone" data-tpl-if="!slots.dropzone">
|
|
1724
1726
|
{{ #l10n:t('dropzonelabel') }}
|
|
1725
1727
|
</div>
|
|
1726
1728
|
<ful-item-list></ful-item-list>
|
|
@@ -1747,6 +1749,7 @@ class InputFile extends Input {
|
|
|
1747
1749
|
this.multiple = observed.multiple;
|
|
1748
1750
|
this.itemlist = observed.itemlist;
|
|
1749
1751
|
this.dropzone = observed.dropzone;
|
|
1752
|
+
this.maxfiles = observed.maxfiles;
|
|
1750
1753
|
this.maxfilesize = observed.maxfilesize;
|
|
1751
1754
|
this.maxtotalsize = observed.maxtotalsize;
|
|
1752
1755
|
this.#warnings.addEventListener('animationend', e => {
|
|
@@ -1788,13 +1791,14 @@ class InputFile extends Input {
|
|
|
1788
1791
|
this.#ensureAcceptable();
|
|
1789
1792
|
this.#ensureFileSizes();
|
|
1790
1793
|
this.#ensureTotalSize();
|
|
1794
|
+
this.#ensureFilesCount();
|
|
1791
1795
|
this.template('items').withOverlay({ files: this.files }).withModule('bytes', { format: this.#formatByteSize }).renderTo(this.#items);
|
|
1792
1796
|
}
|
|
1793
1797
|
warning(key, args) {
|
|
1794
1798
|
this.template('warning').withOverlay({ key, args }).renderTo(this.#warnings);
|
|
1795
1799
|
}
|
|
1796
1800
|
#ensureAcceptable() {
|
|
1797
|
-
if (!this.#accept) {
|
|
1801
|
+
if (!this.#accept.length) {
|
|
1798
1802
|
return;
|
|
1799
1803
|
}
|
|
1800
1804
|
const unacceptable = [...this.files]
|
|
@@ -1803,11 +1807,23 @@ class InputFile extends Input {
|
|
|
1803
1807
|
if (unacceptable.length === 0) {
|
|
1804
1808
|
return;
|
|
1805
1809
|
}
|
|
1806
|
-
this.warning('unaccepptablefiletype', this.#accept.join(","));
|
|
1810
|
+
this.warning('unaccepptablefiletype', this.#accept.join(", "));
|
|
1807
1811
|
const dt = new DataTransfer();
|
|
1808
1812
|
[...this.files].filter(f => !unacceptable.includes(f)).forEach(f => dt.items.add(f));
|
|
1809
1813
|
this.files = dt.files;
|
|
1810
1814
|
}
|
|
1815
|
+
#ensureFilesCount() {
|
|
1816
|
+
if (this.#maxfiles === null) {
|
|
1817
|
+
return;
|
|
1818
|
+
}
|
|
1819
|
+
if (this.files.length <= this.#maxfiles) {
|
|
1820
|
+
return;
|
|
1821
|
+
}
|
|
1822
|
+
this.warning('maxfilesexceeded');
|
|
1823
|
+
const dt = new DataTransfer();
|
|
1824
|
+
this.files = dt.files;
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1811
1827
|
#ensureFileSizes() {
|
|
1812
1828
|
if (this.#maxfilesize === null) {
|
|
1813
1829
|
return;
|
|
@@ -1873,6 +1889,19 @@ class InputFile extends Input {
|
|
|
1873
1889
|
set value(v) {
|
|
1874
1890
|
//TODO:
|
|
1875
1891
|
}
|
|
1892
|
+
get totalsize() {
|
|
1893
|
+
return Array.from(this.files).reduce((a, f) => a + f.size, 0);
|
|
1894
|
+
}
|
|
1895
|
+
#maxfiles;
|
|
1896
|
+
get maxfiles() {
|
|
1897
|
+
return this.#maxfiles;
|
|
1898
|
+
}
|
|
1899
|
+
set maxfiles(v) {
|
|
1900
|
+
this.#maxfiles = v;
|
|
1901
|
+
this.reflect(() => {
|
|
1902
|
+
Attributes.set(this, 'maxfiles', v);
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1876
1905
|
#maxfilesize;
|
|
1877
1906
|
get maxfilesize() {
|
|
1878
1907
|
return this.#maxfilesize;
|
|
@@ -1880,7 +1909,7 @@ class InputFile extends Input {
|
|
|
1880
1909
|
set maxfilesize(v) {
|
|
1881
1910
|
this.#maxfilesize = v;
|
|
1882
1911
|
this.reflect(() => {
|
|
1883
|
-
|
|
1912
|
+
Attributes.set(this, 'maxfilesize', v);
|
|
1884
1913
|
});
|
|
1885
1914
|
}
|
|
1886
1915
|
#maxtotalsize;
|
|
@@ -1890,7 +1919,7 @@ class InputFile extends Input {
|
|
|
1890
1919
|
set maxtotalsize(v) {
|
|
1891
1920
|
this.#maxtotalsize = v;
|
|
1892
1921
|
this.reflect(() => {
|
|
1893
|
-
|
|
1922
|
+
Attributes.set(this, 'maxtotalsize', v);
|
|
1894
1923
|
});
|
|
1895
1924
|
}
|
|
1896
1925
|
#useItemlist;
|
|
@@ -1912,7 +1941,7 @@ class InputFile extends Input {
|
|
|
1912
1941
|
this.reflect(() => {
|
|
1913
1942
|
Attributes.toggle(this, "dropzone", v);
|
|
1914
1943
|
});
|
|
1915
|
-
}
|
|
1944
|
+
}
|
|
1916
1945
|
}
|
|
1917
1946
|
|
|
1918
1947
|
class RemoteLoader {
|
|
@@ -1983,16 +2012,16 @@ class PartialRemoteLoader {
|
|
|
1983
2012
|
this.#responseMapper = responseMapper;
|
|
1984
2013
|
}
|
|
1985
2014
|
async exact(...keys) {
|
|
1986
|
-
const
|
|
2015
|
+
const response = await this.#http.request(this.#method, this.#url)
|
|
1987
2016
|
.param("k", ...keys)
|
|
1988
2017
|
.fetchJson();
|
|
1989
|
-
return this.#responseMapper(
|
|
2018
|
+
return this.#responseMapper(response);
|
|
1990
2019
|
}
|
|
1991
2020
|
async load(needle) {
|
|
1992
|
-
const
|
|
2021
|
+
const response = await this.#http.request(this.#method, this.#url)
|
|
1993
2022
|
.param("s", needle)
|
|
1994
2023
|
.fetchJson();
|
|
1995
|
-
return this.#responseMapper(
|
|
2024
|
+
return this.#responseMapper(response);
|
|
1996
2025
|
}
|
|
1997
2026
|
}
|
|
1998
2027
|
|
|
@@ -2044,19 +2073,22 @@ class SelectLoader {
|
|
|
2044
2073
|
}
|
|
2045
2074
|
static #responseMapperFrom(el) {
|
|
2046
2075
|
if (el.hasAttribute("k-expr") && el.hasAttribute("l-expr")) {
|
|
2047
|
-
return
|
|
2048
|
-
const
|
|
2049
|
-
return
|
|
2050
|
-
evaluator.
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2076
|
+
return response => {
|
|
2077
|
+
const rows = registry.evaluator().withOverlay(response).evaluateExpression(el.getAttribute("d-expr") ?? 'self');
|
|
2078
|
+
return rows.map(row => {
|
|
2079
|
+
const evaluator = registry.evaluator().withOverlay(row);
|
|
2080
|
+
return [
|
|
2081
|
+
evaluator.evaluateExpression(el.getAttribute("k-expr")),
|
|
2082
|
+
evaluator.evaluateExpression(el.getAttribute("l-expr")),
|
|
2083
|
+
evaluator.evaluateExpression(el.getAttribute("m-expr") ?? 'self'),
|
|
2084
|
+
];
|
|
2085
|
+
})
|
|
2054
2086
|
};
|
|
2055
2087
|
}
|
|
2056
2088
|
if (el.hasAttribute("response-mapper")) {
|
|
2057
2089
|
return registry.component(el.getAttribute("response-mapper"));
|
|
2058
2090
|
}
|
|
2059
|
-
return
|
|
2091
|
+
return response => response;
|
|
2060
2092
|
}
|
|
2061
2093
|
}
|
|
2062
2094
|
|
|
@@ -2200,7 +2232,7 @@ class Select extends ParsedElement {
|
|
|
2200
2232
|
}
|
|
2201
2233
|
async render({ slots, observed, disabled }) {
|
|
2202
2234
|
const name = this.getAttribute("name");
|
|
2203
|
-
this.#loader = registry.component(this.getAttribute("loader") ?? 'loaders:select').create(this, {options: slots.options});
|
|
2235
|
+
this.#loader = registry.component(this.getAttribute("loader") ?? 'loaders:select').create(this, { options: slots.options });
|
|
2204
2236
|
|
|
2205
2237
|
this.#multiple = this.hasAttribute("multiple");
|
|
2206
2238
|
await this.#loader.prefetch?.();
|
|
@@ -2341,7 +2373,7 @@ class Select extends ParsedElement {
|
|
|
2341
2373
|
this.replaceChildren(fragment);
|
|
2342
2374
|
}
|
|
2343
2375
|
async withLoader(fn) {
|
|
2344
|
-
await fn(this.#loader);
|
|
2376
|
+
return await fn(this.#loader);
|
|
2345
2377
|
}
|
|
2346
2378
|
#changed() {
|
|
2347
2379
|
const selection = [...this.#values.entries()].map(e => ({ key: e[0], label: e[1][0], metadata: e[1].slice(1) }));
|
|
@@ -2837,8 +2869,8 @@ class TableSchemaParser {
|
|
|
2837
2869
|
rowsTr.setAttribute(attr, value ?? '');
|
|
2838
2870
|
}
|
|
2839
2871
|
const columns = Nodes.queryChildrenAll(schema, "column");
|
|
2840
|
-
const sort = columns.filter(v => v.hasAttribute('order')).map(v => ({sorter: v.getAttribute("sorter"), order: v.getAttribute("order")}))[0] ?? null;
|
|
2841
|
-
for(var column of columns){
|
|
2872
|
+
const sort = columns.filter(v => v.hasAttribute('order')).map(v => ({ sorter: v.getAttribute("sorter"), order: v.getAttribute("order") }))[0] ?? null;
|
|
2873
|
+
for (var column of columns) {
|
|
2842
2874
|
const maybeTitleTag = Nodes.queryChildren(column, 'title');
|
|
2843
2875
|
const sorter = column.getAttribute("sorter");
|
|
2844
2876
|
const order = column.getAttribute("order");
|
|
@@ -2847,12 +2879,12 @@ class TableSchemaParser {
|
|
|
2847
2879
|
column.removeAttribute("sorter");
|
|
2848
2880
|
column.removeAttribute("order");
|
|
2849
2881
|
column.removeAttribute("title");
|
|
2850
|
-
const wrappedTitleNode = (!sorter &&
|
|
2882
|
+
const wrappedTitleNode = (!sorter && !order) ? titleNode : (() => {
|
|
2851
2883
|
const fulSorter = document.createElement("ful-sorter");
|
|
2852
|
-
if(sorter){
|
|
2884
|
+
if (sorter) {
|
|
2853
2885
|
fulSorter.setAttribute("sorter", sorter);
|
|
2854
2886
|
}
|
|
2855
|
-
if(order){
|
|
2887
|
+
if (order) {
|
|
2856
2888
|
fulSorter.setAttribute("order", order);
|
|
2857
2889
|
}
|
|
2858
2890
|
fulSorter.append(titleNode);
|
|
@@ -2872,14 +2904,32 @@ class TableSchemaParser {
|
|
|
2872
2904
|
}
|
|
2873
2905
|
|
|
2874
2906
|
return {
|
|
2875
|
-
headersTemplate: template.withOverlay({inHeaders: true, inRows: false}).withFragment(Fragments.from(headersTr)),
|
|
2876
|
-
rowsTemplate: template.withOverlay({inHeaders: false, inRows: true}).withFragment(Fragments.from(rowsTr)),
|
|
2907
|
+
headersTemplate: template.withOverlay({ inHeaders: true, inRows: false }).withFragment(Fragments.from(headersTr)),
|
|
2908
|
+
rowsTemplate: template.withOverlay({ inHeaders: false, inRows: true }).withFragment(Fragments.from(rowsTr)),
|
|
2877
2909
|
sort: sort,
|
|
2878
2910
|
length: columns.length
|
|
2879
2911
|
}
|
|
2880
2912
|
}
|
|
2881
2913
|
}
|
|
2882
2914
|
|
|
2915
|
+
|
|
2916
|
+
|
|
2917
|
+
class InMemoryTableLoader {
|
|
2918
|
+
#data
|
|
2919
|
+
constructor(data) {
|
|
2920
|
+
this.#data = data;
|
|
2921
|
+
}
|
|
2922
|
+
async load(pageRequest, sortRequest, filterRequest) {
|
|
2923
|
+
return {
|
|
2924
|
+
page: this.#data,
|
|
2925
|
+
size: this.#data.length
|
|
2926
|
+
};
|
|
2927
|
+
}
|
|
2928
|
+
update(data) {
|
|
2929
|
+
this.#data = data;
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
|
|
2883
2933
|
class RemoteTableLoader {
|
|
2884
2934
|
#http;
|
|
2885
2935
|
#url;
|
|
@@ -2903,10 +2953,13 @@ class RemoteTableLoader {
|
|
|
2903
2953
|
|
|
2904
2954
|
class TableLoader {
|
|
2905
2955
|
static create(el, conf) {
|
|
2906
|
-
const http = registry.component("http-client");
|
|
2907
2956
|
const url = el.getAttribute("src");
|
|
2908
|
-
|
|
2909
|
-
|
|
2957
|
+
if (url) {
|
|
2958
|
+
const http = registry.component("http-client");
|
|
2959
|
+
const method = el.getAttribute("method") ?? 'GET';
|
|
2960
|
+
return new RemoteTableLoader(http, url, method);
|
|
2961
|
+
}
|
|
2962
|
+
return new InMemoryTableLoader([]);
|
|
2910
2963
|
}
|
|
2911
2964
|
}
|
|
2912
2965
|
|
|
@@ -2980,6 +3033,7 @@ class Table extends ParsedElement {
|
|
|
2980
3033
|
{{{{ schema.rowsTemplate.withOverlay({'rows': pageResponse.data}).render() }}}}
|
|
2981
3034
|
`
|
|
2982
3035
|
};
|
|
3036
|
+
#loader;
|
|
2983
3037
|
#schema;
|
|
2984
3038
|
#body;
|
|
2985
3039
|
#loading;
|
|
@@ -2995,6 +3049,8 @@ class Table extends ParsedElement {
|
|
|
2995
3049
|
const tableWrapper = /** @type HTMLTableElement */ (Nodes.queryChildren(fragment, '.table-wrapper'));
|
|
2996
3050
|
const table = /** @type HTMLTableElement */ (tableWrapper.querySelector("table"));
|
|
2997
3051
|
Attributes.forward('table-', this, table);
|
|
3052
|
+
this.#loader = registry.component(this.getAttribute("loader") ?? 'loaders:table').create(this);
|
|
3053
|
+
|
|
2998
3054
|
this.#schema = schema;
|
|
2999
3055
|
this.#body = table.querySelector(':scope > tbody');
|
|
3000
3056
|
this.#loading = table.querySelector(":scope > tbody[data-ref=loading]");
|
|
@@ -3047,8 +3103,7 @@ class Table extends ParsedElement {
|
|
|
3047
3103
|
this.#feedback.setAttribute("hidden", "");
|
|
3048
3104
|
this.#noAutoload.setAttribute("hidden", "");
|
|
3049
3105
|
try {
|
|
3050
|
-
const
|
|
3051
|
-
const pageResponse = await loader.load(pageRequest, sortRequest, filterRequest);
|
|
3106
|
+
const pageResponse = await this.#loader.load(pageRequest, sortRequest, filterRequest);
|
|
3052
3107
|
this.#latestRequest = { pageRequest, sortRequest, filterRequest };
|
|
3053
3108
|
this.#update(pageRequest, sortRequest, filterRequest, pageResponse);
|
|
3054
3109
|
} catch (/** @type any */error) {
|
|
@@ -3062,14 +3117,15 @@ class Table extends ParsedElement {
|
|
|
3062
3117
|
throw error;
|
|
3063
3118
|
}
|
|
3064
3119
|
}
|
|
3065
|
-
|
|
3120
|
+
async withLoader(fn) {
|
|
3121
|
+
return await fn(this.#loader);
|
|
3122
|
+
}
|
|
3066
3123
|
async resetWithFilter(filterRequest) {
|
|
3067
3124
|
return await this.load({
|
|
3068
3125
|
page: 0,
|
|
3069
3126
|
size: this.#latestRequest.pageRequest.size
|
|
3070
3127
|
}, this.#latestRequest.sortRequest, filterRequest);
|
|
3071
3128
|
}
|
|
3072
|
-
|
|
3073
3129
|
#update(pageRequest, sortRequest, filterRequest, pageResponse) {
|
|
3074
3130
|
this.#loading.setAttribute("hidden", "");
|
|
3075
3131
|
this.#body.replaceChildren(this.template('row').withOverlay({
|