@controleonline/ui-default 1.0.263 → 1.0.264
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/AGENTS.md +48 -47
- package/package.json +3 -6
- package/src/react/components/errors/DefaultErrors.js +360 -360
- package/src/react/components/files/DefaultFile.js +46 -46
- package/src/react/components/filters/CompactFilterSelector.js +22 -3
- package/src/react/components/filters/DefaultColumnFilter.js +15 -13
- package/src/react/components/filters/DefaultExternalFilters.js +44 -39
- package/src/react/components/filters/DefaultSearch.js +140 -103
- package/src/react/components/filters/DefaultSearch.styles.js +65 -70
- package/src/react/components/form/DefaultForm.js +200 -198
- package/src/react/components/help/DefaultTooltip.js +87 -87
- package/src/react/components/help/DefaultTooltip.styles.js +61 -61
- package/src/react/components/inputs/DefaultInput.js +162 -160
- package/src/react/components/inputs/DefaultSelect.js +203 -192
- package/src/react/components/map/DefaultGoogleMap.styles.js +115 -9
- package/src/react/components/map/DefaultGoogleMap.web.js +560 -446
- package/src/react/components/map/DefaultMap.native.js +73 -71
- package/src/react/components/map/DefaultMap.styles.js +16 -16
- package/src/react/components/map/DefaultMap.web.js +68 -66
- package/src/react/components/map/DefaultNativeMap.native.js +307 -183
- package/src/react/components/map/DefaultNativeMap.shared.js +439 -340
- package/src/react/components/map/DefaultNativeMap.styles.js +156 -122
- package/src/react/components/table/DefaultTable.js +529 -355
- package/src/react/components/table/DefaultTable.styles.js +30 -39
- package/src/react/index.js +10 -10
- package/src/tests/react/components/errors/DefaultErrors.test.js +162 -162
- package/src/tests/react/components/files/DefaultFile.test.js +80 -80
- package/src/tests/react/components/inputs/DefaultSelect.test.js +93 -0
- package/src/tests/react/components/table/DefaultTable.test.js +334 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
1
2
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
3
|
import {
|
|
3
4
|
FlatList,
|
|
@@ -16,7 +17,7 @@ import Formatter from '@controleonline/ui-common/src/utils/formatter.js';
|
|
|
16
17
|
import StateStore from '@controleonline/ui-layout/src/react/components/StateStore';
|
|
17
18
|
import { getDateRange } from '@controleonline/ui-common/src/react/utils/dateRangeFilter';
|
|
18
19
|
import { formatStoreColumnLabel } from '@controleonline/ui-common/src/react/utils/storeColumns';
|
|
19
|
-
import { resolveThemePalette
|
|
20
|
+
import { resolveThemePalette } from '@controleonline/../../src/styles/branding';
|
|
20
21
|
import { colors } from '@controleonline/../../src/styles/colors';
|
|
21
22
|
import DefaultColumnFilter from '../filters/DefaultColumnFilter';
|
|
22
23
|
import DefaultSearch from '../filters/DefaultSearch';
|
|
@@ -73,20 +74,29 @@ const resolveListLoadParams = ({currentCompanyId, listStoreName}) => {
|
|
|
73
74
|
return {};
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
return
|
|
77
|
+
return listStoreName === 'categories'
|
|
78
|
+
? {company: currentCompanyId}
|
|
79
|
+
: {people: currentCompanyId};
|
|
77
80
|
};
|
|
78
81
|
|
|
79
|
-
const resolveColumnListLoadParams = ({
|
|
82
|
+
export const resolveColumnListLoadParams = ({
|
|
83
|
+
column,
|
|
84
|
+
currentCompanyId,
|
|
85
|
+
requestParams = {},
|
|
86
|
+
}) => {
|
|
80
87
|
const listStoreName = resolveStoreNameFromList(column?.list);
|
|
81
88
|
const companyScopedParams = resolveListLoadParams({
|
|
82
89
|
currentCompanyId,
|
|
83
90
|
listStoreName,
|
|
84
91
|
});
|
|
92
|
+
const resolvedCustomParams = typeof column?.listRequestParams === 'function'
|
|
93
|
+
? column.listRequestParams({currentCompanyId, requestParams})
|
|
94
|
+
: column?.listRequestParams;
|
|
85
95
|
const customParams =
|
|
86
|
-
|
|
87
|
-
typeof
|
|
88
|
-
!Array.isArray(
|
|
89
|
-
?
|
|
96
|
+
resolvedCustomParams &&
|
|
97
|
+
typeof resolvedCustomParams === 'object' &&
|
|
98
|
+
!Array.isArray(resolvedCustomParams)
|
|
99
|
+
? resolvedCustomParams
|
|
90
100
|
: {};
|
|
91
101
|
|
|
92
102
|
return {
|
|
@@ -492,33 +502,35 @@ const DefaultTable = ({
|
|
|
492
502
|
searchProps = null,
|
|
493
503
|
toolbarActions = [],
|
|
494
504
|
showColumnFiltersButton = true,
|
|
495
|
-
showTotalItemsInFooter = true,
|
|
496
|
-
showTotalItemsInCompactToolbar = false,
|
|
497
|
-
showRowActions = true,
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
505
|
+
showTotalItemsInFooter = true,
|
|
506
|
+
showTotalItemsInCompactToolbar = false,
|
|
507
|
+
showRowActions = true,
|
|
508
|
+
rowStyle = null,
|
|
509
|
+
sort = null,
|
|
510
|
+
storeName = '',
|
|
511
|
+
summary = null,
|
|
512
|
+
summaryLabels = null,
|
|
513
|
+
totalItems = null,
|
|
514
|
+
totalItemsLabel = null,
|
|
515
|
+
totalItemsText = null,
|
|
516
|
+
footerComponent = null,
|
|
517
|
+
visibleColumnsPreferenceKey = '',
|
|
506
518
|
}) => {
|
|
507
519
|
const { width } = useWindowDimensions();
|
|
508
520
|
const store = useStore(storeName);
|
|
521
|
+
const visibleColumnsStorageKey = visibleColumnsPreferenceKey || storeName;
|
|
509
522
|
const peopleStore = useStore('people');
|
|
510
523
|
const themeStore = useStore('theme');
|
|
511
524
|
const [editingCell, setEditingCell] = useState(null);
|
|
512
|
-
const [editingRow, setEditingRow] = useState(null);
|
|
525
|
+
const [editingRow, setEditingRow] = useState(null);
|
|
513
526
|
const [formMode, setFormMode] = useState('edit');
|
|
514
527
|
const [isColumnMenuOpen, setIsColumnMenuOpen] = useState(false);
|
|
515
|
-
const [,
|
|
528
|
+
const [listOptionsByColumn, setListOptionsByColumn] = useState({});
|
|
516
529
|
const [savingCell, setSavingCell] = useState(null);
|
|
517
530
|
const [showColumnFilters, setShowColumnFilters] = useState(false);
|
|
518
531
|
const [tableContainerWidth, setTableContainerWidth] = useState(0);
|
|
519
532
|
const endReachedLockRef = useRef(false);
|
|
520
533
|
const loadedListStoresRef = useRef(new Set());
|
|
521
|
-
const listOptionsWasFocusedRef = useRef(false);
|
|
522
534
|
const previousPaginationStateRef = useRef({
|
|
523
535
|
dataLength: Array.isArray(data) ? data.length : 0,
|
|
524
536
|
filtersKey: JSON.stringify(filters || {}),
|
|
@@ -532,10 +544,10 @@ const DefaultTable = ({
|
|
|
532
544
|
? store.getters.columns
|
|
533
545
|
: columns,
|
|
534
546
|
visibleColumns: resolveStoredVisibleColumnsPreference(
|
|
535
|
-
|
|
547
|
+
visibleColumnsStorageKey,
|
|
536
548
|
),
|
|
537
549
|
}),
|
|
538
|
-
[columns, store?.getters?.columns,
|
|
550
|
+
[columns, store?.getters?.columns, visibleColumnsStorageKey],
|
|
539
551
|
);
|
|
540
552
|
const viewModeSeed = useMemo(
|
|
541
553
|
() =>
|
|
@@ -544,11 +556,12 @@ const DefaultTable = ({
|
|
|
544
556
|
initialViewMode,
|
|
545
557
|
),
|
|
546
558
|
[initialViewMode, visibleColumnsPreferenceKey],
|
|
547
|
-
);
|
|
548
|
-
const [visibleColumns, setVisibleColumns] = useState(() => visibleColumnsSeed);
|
|
549
|
-
const [viewMode, setViewMode] = useState(() => viewModeSeed);
|
|
550
|
-
const
|
|
551
|
-
const {
|
|
559
|
+
);
|
|
560
|
+
const [visibleColumns, setVisibleColumns] = useState(() => visibleColumnsSeed);
|
|
561
|
+
const [viewMode, setViewMode] = useState(() => viewModeSeed);
|
|
562
|
+
const [compactViewMode, setCompactViewMode] = useState(null);
|
|
563
|
+
const { currentCompany } = peopleStore.getters || {};
|
|
564
|
+
const { colors: themeColors } = themeStore.getters;
|
|
552
565
|
const themeTokens = useMemo(
|
|
553
566
|
() => ({...themeColors, ...(currentCompany?.theme?.colors || {})}),
|
|
554
567
|
[currentCompany?.theme?.colors, themeColors],
|
|
@@ -565,22 +578,47 @@ const DefaultTable = ({
|
|
|
565
578
|
const tableSurfaceColor = palette.background;
|
|
566
579
|
const tableTextColor = palette.text;
|
|
567
580
|
const tableMutedColor = palette.textSecondary;
|
|
568
|
-
const
|
|
581
|
+
const panelBackgroundColor = themeColors.panelBackground;
|
|
582
|
+
const panelBorderColor = themeColors.panelBorder;
|
|
583
|
+
const modalBackgroundColor = themeColors.modalBackground;
|
|
584
|
+
const modalBorderColor = themeColors.modalBorder;
|
|
585
|
+
const modalCloseIconColor = themeColors.modalCloseIcon;
|
|
586
|
+
const modalHeaderTextColor = themeColors.modalHeaderText;
|
|
587
|
+
const modalOverlayColor = themeColors.modalOverlay;
|
|
588
|
+
const modalTextColor = themeColors.modalText;
|
|
589
|
+
const checkboxBorderColor = themeColors.checkboxBorder;
|
|
590
|
+
const checkboxSelectedMarkColor = themeColors.checkboxSelectedMark;
|
|
591
|
+
const toolbarBackgroundColor = themeColors.toolbarBackground;
|
|
592
|
+
const toolbarBorderColor = themeColors.toolbarBorder;
|
|
593
|
+
const toolbarCountBackgroundColor = themeColors.badgeBackground;
|
|
594
|
+
const toolbarCountTextColor = themeColors.badgeText;
|
|
595
|
+
const tableActionBackgroundColor = themeColors.tableActionBackground;
|
|
596
|
+
const tableActionBorderColor = themeColors.tableActionBorder;
|
|
597
|
+
const tableActionTextColor = themeColors.tableActionIcon;
|
|
598
|
+
const tableButtonBackgroundColor = themeColors.buttonBackground;
|
|
599
|
+
const tableButtonBorderColor = themeColors.buttonBorder;
|
|
600
|
+
const tableButtonIconColor = themeColors.buttonIcon;
|
|
601
|
+
const tableButtonPressedBackgroundColor = themeColors.buttonPressedBackground;
|
|
602
|
+
const tableButtonPressedBorderColor = themeColors.buttonPressedBorder;
|
|
603
|
+
const tableButtonPressedIconColor = themeColors.buttonPressedIcon;
|
|
604
|
+
const tableButtonTextColor = themeColors.buttonText;
|
|
605
|
+
const tableFilterBackgroundColor = themeColors.tableFilterBackground;
|
|
606
|
+
const tableFilterBorderColor = themeColors.tableFilterBorder;
|
|
607
|
+
const tableFilterTextColor = themeColors.tableFilterText;
|
|
569
608
|
const isFocused = useIsFocused();
|
|
570
609
|
const {showError} = useMessage() || {};
|
|
571
610
|
const autoMode = data === undefined && normalizeText(storeName) !== '';
|
|
572
611
|
const searchKey = searchProps?.searchKey || 'search';
|
|
573
612
|
const storeActions = store?.actions || {};
|
|
613
|
+
const resolvedActions = useMemo(
|
|
614
|
+
() => ({
|
|
615
|
+
...storeActions,
|
|
616
|
+
...(actions || {}),
|
|
617
|
+
}),
|
|
618
|
+
[actions, storeActions],
|
|
619
|
+
);
|
|
574
620
|
const storeColumns = Array.isArray(store?.getters?.columns) ? store.getters.columns : [];
|
|
575
621
|
const columnsForTable = storeColumns.length > 0 ? storeColumns : columns;
|
|
576
|
-
const listColumnsSignature = useMemo(
|
|
577
|
-
() =>
|
|
578
|
-
columnsForTable
|
|
579
|
-
.filter(column => normalizeText(column?.list))
|
|
580
|
-
.map(column => `${getColumnKey(column)}:${normalizeText(column.list)}`)
|
|
581
|
-
.join('|'),
|
|
582
|
-
[columnsForTable],
|
|
583
|
-
);
|
|
584
622
|
const storeFilters = isObject(store?.getters?.filters) ? store.getters.filters : {};
|
|
585
623
|
const requestParamsSeed = isObject(requestParams) ? requestParams : {};
|
|
586
624
|
const initialFiltersSeed = autoMode
|
|
@@ -613,80 +651,119 @@ const DefaultTable = ({
|
|
|
613
651
|
const resolvedSort = autoMode ? autoSort : sort;
|
|
614
652
|
const resolvedFilters = autoMode ? autoFilters : (filters || {});
|
|
615
653
|
const resolvedSearchValue = normalizeText(resolvedFilters?.[searchKey]);
|
|
654
|
+
const resolvedGetOptionsForColumn = useCallback(
|
|
655
|
+
column => {
|
|
656
|
+
const explicitOptions = getOptionsForColumn?.(column);
|
|
657
|
+
if (Array.isArray(explicitOptions)) return explicitOptions;
|
|
658
|
+
|
|
659
|
+
const columnKey = getColumnKey(column);
|
|
660
|
+
return Array.isArray(listOptionsByColumn[columnKey])
|
|
661
|
+
? listOptionsByColumn[columnKey]
|
|
662
|
+
: undefined;
|
|
663
|
+
},
|
|
664
|
+
[getOptionsForColumn, listOptionsByColumn],
|
|
665
|
+
);
|
|
616
666
|
|
|
617
667
|
useEffect(() => {
|
|
618
|
-
|
|
619
|
-
|
|
668
|
+
setListOptionsByColumn({});
|
|
669
|
+
loadedListStoresRef.current.clear();
|
|
670
|
+
}, [currentCompany?.id]);
|
|
671
|
+
|
|
672
|
+
const loadListOptionsForColumns = useCallback(
|
|
673
|
+
(targetColumns = []) => {
|
|
674
|
+
const columnsToLoad = (Array.isArray(targetColumns) ? targetColumns : []).filter(
|
|
675
|
+
column => normalizeText(column?.list),
|
|
676
|
+
);
|
|
677
|
+
|
|
678
|
+
if (columnsToLoad.length === 0) {
|
|
679
|
+
return Promise.resolve([]);
|
|
680
|
+
}
|
|
620
681
|
|
|
621
|
-
|
|
682
|
+
const stores = getAllStores?.() || {};
|
|
683
|
+
const loadPromises = [];
|
|
622
684
|
|
|
623
|
-
|
|
685
|
+
columnsToLoad.forEach(column => {
|
|
686
|
+
const explicitOptions = getOptionsForColumn?.(column);
|
|
687
|
+
if (Array.isArray(explicitOptions)) {
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
624
690
|
|
|
625
|
-
|
|
626
|
-
|
|
691
|
+
const listStoreName = resolveStoreNameFromList(column.list);
|
|
692
|
+
const actionName = resolveListActionName(column.list);
|
|
693
|
+
const listStore = stores?.[listStoreName];
|
|
694
|
+
const listAction = listStore?.actions?.[actionName];
|
|
627
695
|
|
|
628
|
-
|
|
629
|
-
|
|
696
|
+
const listLoadParams = resolveColumnListLoadParams({
|
|
697
|
+
column,
|
|
698
|
+
currentCompanyId: currentCompany?.id,
|
|
699
|
+
requestParams: requestParamsSeed,
|
|
700
|
+
});
|
|
701
|
+
const isCompanyScopedList = Object.keys(listLoadParams).length > 0;
|
|
630
702
|
|
|
631
|
-
|
|
632
|
-
|
|
703
|
+
if (!listStoreName || typeof listAction !== 'function') {
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
633
706
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
707
|
+
if (
|
|
708
|
+
!isCompanyScopedList &&
|
|
709
|
+
Array.isArray(listStore?.getters?.items) &&
|
|
710
|
+
listStore.getters.items.length > 0
|
|
711
|
+
) {
|
|
712
|
+
const columnKey = getColumnKey(column);
|
|
713
|
+
setListOptionsByColumn(current => ({
|
|
714
|
+
...current,
|
|
715
|
+
[columnKey]: normalizeCollectionItems(listStore.getters.items),
|
|
716
|
+
}));
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
638
719
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
720
|
+
const columnKey = getColumnKey(column);
|
|
721
|
+
const loadKey = `${columnKey}:${listStoreName}:${actionName}:${stableSerialize(listLoadParams)}`;
|
|
722
|
+
if (loadedListStoresRef.current.has(loadKey)) {
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
loadedListStoresRef.current.add(loadKey);
|
|
727
|
+
loadPromises.push(
|
|
728
|
+
Promise.resolve(
|
|
729
|
+
listAction({
|
|
730
|
+
...listLoadParams,
|
|
731
|
+
itemsPerPage: LIST_OPTIONS_PAGE_SIZE,
|
|
732
|
+
__storeMeta: {
|
|
733
|
+
dedupeKey: `default-table-list-options:${loadKey}`,
|
|
734
|
+
skipSystemError: true,
|
|
735
|
+
},
|
|
736
|
+
}),
|
|
737
|
+
)
|
|
738
|
+
.then(response => ({columnKey, items: normalizeCollectionItems(response)}))
|
|
739
|
+
.catch(() => {
|
|
740
|
+
loadedListStoresRef.current.delete(loadKey);
|
|
741
|
+
return {columnKey, items: []};
|
|
742
|
+
}),
|
|
743
|
+
);
|
|
642
744
|
});
|
|
643
|
-
const isCompanyScopedList = Object.keys(listLoadParams).length > 0;
|
|
644
|
-
|
|
645
|
-
if (!listStoreName || typeof listAction !== 'function') return;
|
|
646
|
-
if (
|
|
647
|
-
!isCompanyScopedList &&
|
|
648
|
-
Array.isArray(listStore?.getters?.items) &&
|
|
649
|
-
listStore.getters.items.length > 0
|
|
650
|
-
) {
|
|
651
|
-
return;
|
|
652
|
-
}
|
|
653
745
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
loadedListStoresRef.current.delete(loadKey);
|
|
746
|
+
if (loadPromises.length === 0) {
|
|
747
|
+
return Promise.resolve([]);
|
|
657
748
|
}
|
|
658
|
-
if (loadedListStoresRef.current.has(loadKey)) return;
|
|
659
|
-
|
|
660
|
-
loadedListStoresRef.current.add(loadKey);
|
|
661
|
-
loadPromises.push(
|
|
662
|
-
Promise.resolve(
|
|
663
|
-
listAction({
|
|
664
|
-
...listLoadParams,
|
|
665
|
-
itemsPerPage: LIST_OPTIONS_PAGE_SIZE,
|
|
666
|
-
__storeMeta: {
|
|
667
|
-
dedupeKey: `default-table-list-options:${loadKey}`,
|
|
668
|
-
skipSystemError: true,
|
|
669
|
-
},
|
|
670
|
-
}),
|
|
671
|
-
).catch(() => {
|
|
672
|
-
loadedListStoresRef.current.delete(loadKey);
|
|
673
|
-
}),
|
|
674
|
-
);
|
|
675
|
-
});
|
|
676
749
|
|
|
677
|
-
|
|
750
|
+
return Promise.all(loadPromises).then(results => {
|
|
751
|
+
const nextOptionsByColumn = Object.fromEntries(
|
|
752
|
+
results.map(result => [result.columnKey, result.items]),
|
|
753
|
+
);
|
|
678
754
|
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
755
|
+
if (Object.keys(nextOptionsByColumn).length > 0) {
|
|
756
|
+
setListOptionsByColumn(current => ({
|
|
757
|
+
...current,
|
|
758
|
+
...nextOptionsByColumn,
|
|
759
|
+
}));
|
|
760
|
+
}
|
|
685
761
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
}
|
|
689
|
-
|
|
762
|
+
return results;
|
|
763
|
+
});
|
|
764
|
+
},
|
|
765
|
+
[currentCompany?.id, getOptionsForColumn, requestParamsSeed],
|
|
766
|
+
);
|
|
690
767
|
|
|
691
768
|
const buildRequestQuery = useCallback(
|
|
692
769
|
(page, append = false) => {
|
|
@@ -762,7 +839,7 @@ const DefaultTable = ({
|
|
|
762
839
|
|
|
763
840
|
const loadAutoPage = useCallback(
|
|
764
841
|
(page, { append = false } = {}) => {
|
|
765
|
-
if (!autoMode || typeof
|
|
842
|
+
if (!autoMode || typeof resolvedActions.getItems !== 'function') {
|
|
766
843
|
return Promise.resolve([]);
|
|
767
844
|
}
|
|
768
845
|
|
|
@@ -780,7 +857,7 @@ const DefaultTable = ({
|
|
|
780
857
|
|
|
781
858
|
const query = buildRequestQuery(page, append);
|
|
782
859
|
|
|
783
|
-
return Promise.resolve(
|
|
860
|
+
return Promise.resolve(resolvedActions.getItems(query))
|
|
784
861
|
.then(response => {
|
|
785
862
|
if (autoRequestIdRef.current !== requestId) {
|
|
786
863
|
return response;
|
|
@@ -810,7 +887,7 @@ const DefaultTable = ({
|
|
|
810
887
|
}
|
|
811
888
|
});
|
|
812
889
|
},
|
|
813
|
-
[autoMode, autoQuerySignature, buildRequestQuery,
|
|
890
|
+
[autoMode, autoQuerySignature, buildRequestQuery, resolvedActions, showError],
|
|
814
891
|
);
|
|
815
892
|
|
|
816
893
|
const availableColumns = useMemo(
|
|
@@ -854,7 +931,7 @@ const DefaultTable = ({
|
|
|
854
931
|
|
|
855
932
|
useEffect(() => {
|
|
856
933
|
if (!autoMode || !isFocused) return;
|
|
857
|
-
if (typeof
|
|
934
|
+
if (typeof resolvedActions.getItems !== 'function') return;
|
|
858
935
|
if (
|
|
859
936
|
autoLoading ||
|
|
860
937
|
autoLoadingMore ||
|
|
@@ -873,7 +950,7 @@ const DefaultTable = ({
|
|
|
873
950
|
autoQuerySignature,
|
|
874
951
|
isFocused,
|
|
875
952
|
loadAutoPage,
|
|
876
|
-
|
|
953
|
+
resolvedActions,
|
|
877
954
|
]);
|
|
878
955
|
|
|
879
956
|
const tableColumns = useMemo(
|
|
@@ -898,7 +975,7 @@ const DefaultTable = ({
|
|
|
898
975
|
const hasAddInstruction = addConfig === true || (isObject(addConfig) && addConfig.enabled !== false);
|
|
899
976
|
const shouldRenderAddButton =
|
|
900
977
|
hasAddInstruction &&
|
|
901
|
-
(typeof onAdd === 'function' || typeof
|
|
978
|
+
(typeof onAdd === 'function' || typeof resolvedActions.save === 'function');
|
|
902
979
|
const resolvedIsLoading = autoMode ? (autoLoading || autoLoadingMore) : Boolean(isLoading);
|
|
903
980
|
const resolvedData = autoMode
|
|
904
981
|
? (autoHasLoaded && Array.isArray(store?.getters?.items) ? store.getters.items : [])
|
|
@@ -912,13 +989,29 @@ const DefaultTable = ({
|
|
|
912
989
|
[hasRowActions, tableColumns],
|
|
913
990
|
);
|
|
914
991
|
const tableWidth = Math.max(tableContainerWidth, tableMinimumWidth);
|
|
915
|
-
const tableLayoutStyle = useMemo(
|
|
916
|
-
() => (tableWidth > 0 ? { minWidth: tableWidth, width: tableWidth } : null),
|
|
917
|
-
[tableWidth],
|
|
918
|
-
);
|
|
992
|
+
const tableLayoutStyle = useMemo(
|
|
993
|
+
() => (tableWidth > 0 ? { minWidth: tableWidth, width: tableWidth } : null),
|
|
994
|
+
[tableWidth],
|
|
995
|
+
);
|
|
919
996
|
const isCompactView = width > 0 && width <= compactBreakpoint;
|
|
920
997
|
const shouldForceCardsOnCompact = forceCardsOnCompact !== false;
|
|
921
|
-
const effectiveViewMode =
|
|
998
|
+
const effectiveViewMode =
|
|
999
|
+
isCompactView && shouldForceCardsOnCompact
|
|
1000
|
+
? (compactViewMode || 'cards')
|
|
1001
|
+
: viewMode;
|
|
1002
|
+
useEffect(() => {
|
|
1003
|
+
if (!shouldForceCardsOnCompact) {
|
|
1004
|
+
setCompactViewMode(null);
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
if (isCompactView) {
|
|
1009
|
+
setCompactViewMode('cards');
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
setCompactViewMode(null);
|
|
1014
|
+
}, [isCompactView, shouldForceCardsOnCompact]);
|
|
922
1015
|
const emptyStateLabel = resolvedIsLoading
|
|
923
1016
|
? global.t?.t(storeName, 'label', 'loading') || 'Carregando...'
|
|
924
1017
|
: 'Nenhum registro encontrado';
|
|
@@ -994,10 +1087,26 @@ const DefaultTable = ({
|
|
|
994
1087
|
normalizeText(entry.value) !== '',
|
|
995
1088
|
);
|
|
996
1089
|
}, [columnsForTable, resolvedSummary, shouldReadSummary, storeName, summaryLabels, tableColumns]);
|
|
997
|
-
const shouldRenderFooterBar =
|
|
998
|
-
(shouldRenderFooterTotalItems && !shouldRenderCompactToolbarTotalItems) ||
|
|
999
|
-
summaryEntries.length > 0;
|
|
1000
|
-
|
|
1090
|
+
const shouldRenderFooterBar =
|
|
1091
|
+
(shouldRenderFooterTotalItems && !shouldRenderCompactToolbarTotalItems) ||
|
|
1092
|
+
summaryEntries.length > 0;
|
|
1093
|
+
const footerProps = {
|
|
1094
|
+
columns: columnsForTable,
|
|
1095
|
+
resolvedAccentColor,
|
|
1096
|
+
resolvedTotalItemsText,
|
|
1097
|
+
shouldRenderCompactToolbarTotalItems,
|
|
1098
|
+
shouldRenderFooterTotalItems,
|
|
1099
|
+
storeName,
|
|
1100
|
+
summaryEntries,
|
|
1101
|
+
summaryLabels,
|
|
1102
|
+
tableBorderColor,
|
|
1103
|
+
tableMutedColor,
|
|
1104
|
+
tableSurfaceColor,
|
|
1105
|
+
tableTextColor,
|
|
1106
|
+
toolbarCountBackgroundColor,
|
|
1107
|
+
toolbarCountTextColor,
|
|
1108
|
+
};
|
|
1109
|
+
|
|
1001
1110
|
const sortedData = useMemo(() => {
|
|
1002
1111
|
const items = Array.isArray(resolvedData) ? [...resolvedData] : [];
|
|
1003
1112
|
const sortField = resolvedSort?.field;
|
|
@@ -1086,12 +1195,12 @@ const DefaultTable = ({
|
|
|
1086
1195
|
setEditingCell(null);
|
|
1087
1196
|
}, []);
|
|
1088
1197
|
|
|
1089
|
-
const saveCell = useCallback((row, column, nextValue) => {
|
|
1090
|
-
const fieldName = getColumnKey(column);
|
|
1091
|
-
if (!fieldName || typeof
|
|
1092
|
-
clearEdit();
|
|
1093
|
-
return Promise.resolve(null);
|
|
1094
|
-
}
|
|
1198
|
+
const saveCell = useCallback((row, column, nextValue) => {
|
|
1199
|
+
const fieldName = getColumnKey(column);
|
|
1200
|
+
if (!fieldName || typeof resolvedActions.save !== 'function') {
|
|
1201
|
+
clearEdit();
|
|
1202
|
+
return Promise.resolve(null);
|
|
1203
|
+
}
|
|
1095
1204
|
|
|
1096
1205
|
const currentValue = resolveEditValue(column, row);
|
|
1097
1206
|
const normalizedNextValue = nextValue && typeof nextValue === 'object'
|
|
@@ -1111,10 +1220,10 @@ const DefaultTable = ({
|
|
|
1111
1220
|
|
|
1112
1221
|
setSavingCell(cellKey);
|
|
1113
1222
|
|
|
1114
|
-
return
|
|
1115
|
-
.then(savedItem => {
|
|
1116
|
-
onSaved?.(savedItem || { ...row, [fieldName]: nextValue }, row);
|
|
1117
|
-
return savedItem;
|
|
1223
|
+
return resolvedActions.save(payload)
|
|
1224
|
+
.then(savedItem => {
|
|
1225
|
+
onSaved?.(savedItem || { ...row, [fieldName]: nextValue }, row);
|
|
1226
|
+
return savedItem;
|
|
1118
1227
|
})
|
|
1119
1228
|
.catch(error => {
|
|
1120
1229
|
console.error(error);
|
|
@@ -1124,7 +1233,7 @@ const DefaultTable = ({
|
|
|
1124
1233
|
setSavingCell(null);
|
|
1125
1234
|
clearEdit();
|
|
1126
1235
|
});
|
|
1127
|
-
}, [
|
|
1236
|
+
}, [clearEdit, onSaved, resolvedActions]);
|
|
1128
1237
|
|
|
1129
1238
|
const requestSort = useCallback(column => {
|
|
1130
1239
|
if (!isSortableColumn(column)) return;
|
|
@@ -1160,27 +1269,27 @@ const DefaultTable = ({
|
|
|
1160
1269
|
visibleColumnsPreferenceKey,
|
|
1161
1270
|
]);
|
|
1162
1271
|
|
|
1163
|
-
const openEditModal = useCallback(row => {
|
|
1164
|
-
if (typeof onEditRow === 'function') {
|
|
1165
|
-
onEditRow(row);
|
|
1166
|
-
return;
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
setFormMode('edit');
|
|
1170
|
-
setEditingRow(row);
|
|
1171
|
-
}, [onEditRow]);
|
|
1172
|
-
|
|
1272
|
+
const openEditModal = useCallback(row => {
|
|
1273
|
+
if (typeof onEditRow === 'function') {
|
|
1274
|
+
onEditRow(row);
|
|
1275
|
+
return;
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
setFormMode('edit');
|
|
1279
|
+
setEditingRow(row);
|
|
1280
|
+
}, [onEditRow]);
|
|
1281
|
+
|
|
1173
1282
|
const openAddForm = useCallback(() => {
|
|
1174
1283
|
if (typeof onAdd === 'function') {
|
|
1175
1284
|
onAdd();
|
|
1176
1285
|
return;
|
|
1177
1286
|
}
|
|
1178
|
-
|
|
1179
|
-
if (typeof
|
|
1180
|
-
|
|
1181
|
-
setFormMode('create');
|
|
1182
|
-
setEditingRow({});
|
|
1183
|
-
}, [
|
|
1287
|
+
|
|
1288
|
+
if (typeof resolvedActions.save !== 'function') return;
|
|
1289
|
+
|
|
1290
|
+
setFormMode('create');
|
|
1291
|
+
setEditingRow({});
|
|
1292
|
+
}, [onAdd, resolvedActions]);
|
|
1184
1293
|
|
|
1185
1294
|
const closeEditModal = useCallback(() => {
|
|
1186
1295
|
setEditingRow(null);
|
|
@@ -1192,12 +1301,12 @@ const DefaultTable = ({
|
|
|
1192
1301
|
|
|
1193
1302
|
if (autoMode) {
|
|
1194
1303
|
setAutoFilters(resolvedNextFilters);
|
|
1195
|
-
|
|
1304
|
+
resolvedActions.setFilters?.(resolvedNextFilters);
|
|
1196
1305
|
return;
|
|
1197
1306
|
}
|
|
1198
1307
|
|
|
1199
1308
|
onFilterChange?.(resolvedNextFilters);
|
|
1200
|
-
}, [autoMode, onFilterChange,
|
|
1309
|
+
}, [autoMode, onFilterChange, resolvedActions]);
|
|
1201
1310
|
|
|
1202
1311
|
const updateFilter = useCallback((fieldName, value) => {
|
|
1203
1312
|
const nextFilters = { ...(resolvedFilters || {}) };
|
|
@@ -1226,39 +1335,49 @@ const DefaultTable = ({
|
|
|
1226
1335
|
[fieldName]: prev[fieldName] === false,
|
|
1227
1336
|
};
|
|
1228
1337
|
|
|
1229
|
-
|
|
1230
|
-
if (
|
|
1338
|
+
resolvedActions?.setVisibleColumns?.(next);
|
|
1339
|
+
if (visibleColumnsStorageKey) {
|
|
1231
1340
|
persistVisibleColumnsPreference(
|
|
1232
|
-
|
|
1341
|
+
visibleColumnsStorageKey,
|
|
1233
1342
|
next,
|
|
1234
1343
|
);
|
|
1235
1344
|
}
|
|
1236
1345
|
return next;
|
|
1237
1346
|
});
|
|
1238
1347
|
}, [
|
|
1239
|
-
|
|
1348
|
+
resolvedActions,
|
|
1240
1349
|
columnsForTable,
|
|
1241
|
-
|
|
1350
|
+
visibleColumnsStorageKey,
|
|
1242
1351
|
]);
|
|
1243
1352
|
|
|
1244
|
-
const toggleViewMode = useCallback(() => {
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1353
|
+
const toggleViewMode = useCallback(() => {
|
|
1354
|
+
const currentViewMode =
|
|
1355
|
+
isCompactView && shouldForceCardsOnCompact
|
|
1356
|
+
? (compactViewMode || 'cards')
|
|
1357
|
+
: viewMode;
|
|
1358
|
+
const nextViewMode = currentViewMode === 'table' ? 'cards' : 'table';
|
|
1359
|
+
|
|
1360
|
+
if (isCompactView && shouldForceCardsOnCompact) {
|
|
1361
|
+
setCompactViewMode(nextViewMode);
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
setViewMode(nextViewMode);
|
|
1365
|
+
|
|
1366
|
+
if (!visibleColumnsPreferenceKey) {
|
|
1367
|
+
return;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
persistTableViewModePreference(
|
|
1371
|
+
visibleColumnsPreferenceKey,
|
|
1372
|
+
nextViewMode,
|
|
1373
|
+
);
|
|
1374
|
+
}, [
|
|
1375
|
+
compactViewMode,
|
|
1376
|
+
isCompactView,
|
|
1377
|
+
shouldForceCardsOnCompact,
|
|
1378
|
+
viewMode,
|
|
1379
|
+
visibleColumnsPreferenceKey,
|
|
1380
|
+
]);
|
|
1262
1381
|
|
|
1263
1382
|
const handleEndReached = useCallback(() => {
|
|
1264
1383
|
if (
|
|
@@ -1306,7 +1425,8 @@ const DefaultTable = ({
|
|
|
1306
1425
|
column={column}
|
|
1307
1426
|
columns={columnsForTable}
|
|
1308
1427
|
editing={isEditing}
|
|
1309
|
-
getOptionsForColumn={
|
|
1428
|
+
getOptionsForColumn={resolvedGetOptionsForColumn}
|
|
1429
|
+
onBeforeOpen={() => loadListOptionsForColumns([column])}
|
|
1310
1430
|
onCancelEditing={clearEdit}
|
|
1311
1431
|
onSave={value => saveCell(row, column, value)}
|
|
1312
1432
|
onStartEditing={() => beginEdit(row, column)}
|
|
@@ -1325,7 +1445,8 @@ const DefaultTable = ({
|
|
|
1325
1445
|
accentColor={resolvedAccentColor}
|
|
1326
1446
|
column={column}
|
|
1327
1447
|
filters={resolvedFilters}
|
|
1328
|
-
|
|
1448
|
+
onBeforeOpen={column?.list ? () => loadListOptionsForColumns([column]) : null}
|
|
1449
|
+
getOptionsForColumn={resolvedGetOptionsForColumn}
|
|
1329
1450
|
onChange={updateFilter}
|
|
1330
1451
|
storeName={storeName}
|
|
1331
1452
|
style={getColumnStyle(column)}
|
|
@@ -1333,23 +1454,23 @@ const DefaultTable = ({
|
|
|
1333
1454
|
);
|
|
1334
1455
|
};
|
|
1335
1456
|
|
|
1336
|
-
const renderToolbarAction = action => {
|
|
1337
|
-
if (!action || action.hidden) return null;
|
|
1338
|
-
|
|
1339
|
-
const isActive = action.active === true;
|
|
1340
|
-
const hasLabel = normalizeText(action.label) !== '';
|
|
1341
|
-
const actionColor = action.color ||
|
|
1342
|
-
|
|
1343
|
-
return (
|
|
1344
|
-
<TouchableOpacity
|
|
1345
|
-
key={action.key || action.icon || action.label}
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
action.style,
|
|
1352
|
-
]}
|
|
1457
|
+
const renderToolbarAction = action => {
|
|
1458
|
+
if (!action || action.hidden) return null;
|
|
1459
|
+
|
|
1460
|
+
const isActive = action.active === true;
|
|
1461
|
+
const hasLabel = normalizeText(action.label) !== '';
|
|
1462
|
+
const actionColor = action.color || tableActionTextColor;
|
|
1463
|
+
|
|
1464
|
+
return (
|
|
1465
|
+
<TouchableOpacity
|
|
1466
|
+
key={action.key || action.icon || action.label}
|
|
1467
|
+
accessibilityRole="button"
|
|
1468
|
+
accessibilityLabel={action.accessibilityLabel || action.label || action.key || action.icon}
|
|
1469
|
+
style={[
|
|
1470
|
+
styles.toolbarButton,
|
|
1471
|
+
{ backgroundColor: tableActionBackgroundColor, borderColor: tableActionBorderColor },
|
|
1472
|
+
action.style,
|
|
1473
|
+
]}
|
|
1353
1474
|
activeOpacity={0.82}
|
|
1354
1475
|
disabled={action.disabled === true}
|
|
1355
1476
|
onPress={action.onPress}
|
|
@@ -1365,12 +1486,12 @@ const DefaultTable = ({
|
|
|
1365
1486
|
<Text style={[styles.toolbarActionLabel, { color: actionColor }, action.labelStyle]} numberOfLines={1}>
|
|
1366
1487
|
{action.label}
|
|
1367
1488
|
</Text>
|
|
1368
|
-
) : null}
|
|
1369
|
-
{action.badge !== undefined && action.badge !== null ? (
|
|
1370
|
-
<Text style={[styles.toolbarBadgeText, { color: action.badgeColor ||
|
|
1371
|
-
{action.badge}
|
|
1372
|
-
</Text>
|
|
1373
|
-
) : null}
|
|
1489
|
+
) : null}
|
|
1490
|
+
{action.badge !== undefined && action.badge !== null ? (
|
|
1491
|
+
<Text style={[styles.toolbarBadgeText, { color: action.badgeColor || tableActionTextColor }]}>
|
|
1492
|
+
{action.badge}
|
|
1493
|
+
</Text>
|
|
1494
|
+
) : null}
|
|
1374
1495
|
</TouchableOpacity>
|
|
1375
1496
|
);
|
|
1376
1497
|
};
|
|
@@ -1385,8 +1506,8 @@ const DefaultTable = ({
|
|
|
1385
1506
|
[columnsForTable],
|
|
1386
1507
|
);
|
|
1387
1508
|
|
|
1388
|
-
const buildRowHelpers = useCallback(
|
|
1389
|
-
row => {
|
|
1509
|
+
const buildRowHelpers = useCallback(
|
|
1510
|
+
row => {
|
|
1390
1511
|
const openEdit = () => openEditModal(row);
|
|
1391
1512
|
const openRow = typeof onRowPress === 'function' ? () => onRowPress(row) : null;
|
|
1392
1513
|
const renderValue = (fieldName, fallback = '-') => {
|
|
@@ -1402,7 +1523,7 @@ const DefaultTable = ({
|
|
|
1402
1523
|
const isEditing = editingCell === cellKey;
|
|
1403
1524
|
const isSaving = savingCell === cellKey;
|
|
1404
1525
|
|
|
1405
|
-
return (
|
|
1526
|
+
return (
|
|
1406
1527
|
<DefaultInput
|
|
1407
1528
|
accentColor={options.accentColor || resolvedAccentColor}
|
|
1408
1529
|
column={column}
|
|
@@ -1410,14 +1531,15 @@ const DefaultTable = ({
|
|
|
1410
1531
|
containerStyle={options.containerStyle}
|
|
1411
1532
|
displayValue={options.displayValue}
|
|
1412
1533
|
editing={isEditing}
|
|
1413
|
-
getOptionsForColumn={
|
|
1534
|
+
getOptionsForColumn={resolvedGetOptionsForColumn}
|
|
1414
1535
|
inputStyle={options.inputStyle}
|
|
1415
1536
|
label={options.label}
|
|
1416
|
-
numberOfLines={options.numberOfLines}
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1537
|
+
numberOfLines={options.numberOfLines}
|
|
1538
|
+
onBeforeOpen={() => loadListOptionsForColumns([column])}
|
|
1539
|
+
onCancelEditing={clearEdit}
|
|
1540
|
+
onSave={value => saveCell(row, column, value)}
|
|
1541
|
+
onStartEditing={() => beginEdit(row, column)}
|
|
1542
|
+
readTextStyle={options.readTextStyle || options.textStyle}
|
|
1421
1543
|
row={row}
|
|
1422
1544
|
saving={isSaving}
|
|
1423
1545
|
showLabel={options.showLabel}
|
|
@@ -1441,24 +1563,36 @@ const DefaultTable = ({
|
|
|
1441
1563
|
columnsForTable,
|
|
1442
1564
|
editingCell,
|
|
1443
1565
|
getColumnByField,
|
|
1444
|
-
|
|
1566
|
+
resolvedGetOptionsForColumn,
|
|
1445
1567
|
openEditModal,
|
|
1446
1568
|
onRowPress,
|
|
1447
1569
|
saveCell,
|
|
1448
1570
|
savingCell,
|
|
1449
1571
|
storeName,
|
|
1450
|
-
],
|
|
1451
|
-
);
|
|
1452
|
-
|
|
1453
|
-
const
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1572
|
+
],
|
|
1573
|
+
);
|
|
1574
|
+
|
|
1575
|
+
const resolveRowStyle = useCallback(
|
|
1576
|
+
(row, index) => {
|
|
1577
|
+
if (typeof rowStyle === 'function') {
|
|
1578
|
+
return rowStyle(row, index);
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
return rowStyle;
|
|
1582
|
+
},
|
|
1583
|
+
[rowStyle],
|
|
1584
|
+
);
|
|
1585
|
+
|
|
1586
|
+
const renderCardItem = (row, index = 0) => {
|
|
1587
|
+
const helpers = buildRowHelpers(row);
|
|
1588
|
+
const rowStyleValue = resolveRowStyle(row, index);
|
|
1589
|
+
|
|
1590
|
+
if (typeof renderCard === 'function') {
|
|
1591
|
+
return (
|
|
1592
|
+
<View key={row?.['@id'] || row?.id} style={[styles.cardItem, rowStyleValue]}>
|
|
1593
|
+
{renderCard({
|
|
1594
|
+
item: row,
|
|
1595
|
+
openEdit: helpers.openEdit,
|
|
1462
1596
|
openRow: helpers.openRow,
|
|
1463
1597
|
renderField: helpers.renderField,
|
|
1464
1598
|
renderValue: helpers.renderValue,
|
|
@@ -1476,11 +1610,18 @@ const DefaultTable = ({
|
|
|
1476
1610
|
) : null}
|
|
1477
1611
|
</View>
|
|
1478
1612
|
);
|
|
1479
|
-
}
|
|
1480
|
-
|
|
1481
|
-
return (
|
|
1482
|
-
<View
|
|
1483
|
-
{
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
return (
|
|
1616
|
+
<View
|
|
1617
|
+
key={row?.['@id'] || row?.id}
|
|
1618
|
+
style={[
|
|
1619
|
+
styles.defaultCard,
|
|
1620
|
+
{ backgroundColor: tableSurfaceColor, borderColor: tableBorderColor },
|
|
1621
|
+
rowStyleValue,
|
|
1622
|
+
]}
|
|
1623
|
+
>
|
|
1624
|
+
{tableColumns.map(column => (
|
|
1484
1625
|
<View key={getColumnKey(column)} style={styles.defaultCardLine}>
|
|
1485
1626
|
<Text style={[styles.defaultCardLabel, { color: tableMutedColor }]}>
|
|
1486
1627
|
{formatStoreColumnLabel({
|
|
@@ -1539,23 +1680,29 @@ const DefaultTable = ({
|
|
|
1539
1680
|
);
|
|
1540
1681
|
};
|
|
1541
1682
|
|
|
1542
|
-
const renderTableItem = ({ item: row, index }) => {
|
|
1543
|
-
const hasRowPress = typeof onRowPress === 'function';
|
|
1544
|
-
const RowComponent = hasRowPress ? TouchableOpacity : View;
|
|
1545
|
-
const
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1683
|
+
const renderTableItem = ({ item: row, index }) => {
|
|
1684
|
+
const hasRowPress = typeof onRowPress === 'function';
|
|
1685
|
+
const RowComponent = hasRowPress ? TouchableOpacity : View;
|
|
1686
|
+
const rowStyleValue = resolveRowStyle(row, index);
|
|
1687
|
+
const rowPressProps = hasRowPress
|
|
1688
|
+
? {
|
|
1689
|
+
activeOpacity: 0.84,
|
|
1690
|
+
onPress: () => onRowPress(row),
|
|
1691
|
+
}
|
|
1550
1692
|
: {};
|
|
1551
1693
|
const rowBackgroundColor = index % 2 === 0 ? tableOddColor : tableEvenColor;
|
|
1552
1694
|
|
|
1553
|
-
return (
|
|
1554
|
-
<RowComponent
|
|
1555
|
-
key={getRowKey(row)}
|
|
1556
|
-
style={[
|
|
1557
|
-
|
|
1558
|
-
|
|
1695
|
+
return (
|
|
1696
|
+
<RowComponent
|
|
1697
|
+
key={getRowKey(row)}
|
|
1698
|
+
style={[
|
|
1699
|
+
styles.row,
|
|
1700
|
+
tableLayoutStyle,
|
|
1701
|
+
{ backgroundColor: rowBackgroundColor, borderBottomColor: tableBorderColor },
|
|
1702
|
+
rowStyleValue,
|
|
1703
|
+
]}
|
|
1704
|
+
{...rowPressProps}
|
|
1705
|
+
>
|
|
1559
1706
|
{tableColumns.map(column => (
|
|
1560
1707
|
<React.Fragment key={getColumnKey(column)}>
|
|
1561
1708
|
{renderEditableCell(row, column)}
|
|
@@ -1579,32 +1726,33 @@ const DefaultTable = ({
|
|
|
1579
1726
|
const isCreate = formMode === 'create';
|
|
1580
1727
|
|
|
1581
1728
|
return (
|
|
1582
|
-
<Modal visible={Boolean(editingRow)} transparent animationType="fade" onRequestClose={closeEditModal}>
|
|
1583
|
-
<View style={[styles.modalOverlay, { backgroundColor:
|
|
1584
|
-
<View style={[styles.modalCard, { borderColor:
|
|
1585
|
-
<View style={[styles.modalHeader, { borderBottomColor:
|
|
1586
|
-
<Text style={[styles.modalTitle, { color:
|
|
1587
|
-
{isCreate
|
|
1588
|
-
? global.t?.t(storeName, 'button', 'add') || 'Adicionar'
|
|
1589
|
-
: global.t?.t(storeName, 'button', 'edit') || 'Editar'}
|
|
1590
|
-
</Text>
|
|
1591
|
-
<TouchableOpacity
|
|
1592
|
-
style={[styles.modalCloseButton, { borderColor:
|
|
1593
|
-
onPress={closeEditModal}>
|
|
1594
|
-
<Icon name="x" size={18} color={
|
|
1595
|
-
</TouchableOpacity>
|
|
1596
|
-
</View>
|
|
1729
|
+
<Modal visible={Boolean(editingRow)} transparent animationType="fade" onRequestClose={closeEditModal}>
|
|
1730
|
+
<View style={[styles.modalOverlay, { backgroundColor: modalOverlayColor }]}>
|
|
1731
|
+
<View style={[styles.modalCard, { borderColor: modalBorderColor, backgroundColor: modalBackgroundColor }]}>
|
|
1732
|
+
<View style={[styles.modalHeader, { borderBottomColor: modalBorderColor }]}>
|
|
1733
|
+
<Text style={[styles.modalTitle, { color: modalHeaderTextColor }]}>
|
|
1734
|
+
{isCreate
|
|
1735
|
+
? global.t?.t(storeName, 'button', 'add') || 'Adicionar'
|
|
1736
|
+
: global.t?.t(storeName, 'button', 'edit') || 'Editar'}
|
|
1737
|
+
</Text>
|
|
1738
|
+
<TouchableOpacity
|
|
1739
|
+
style={[styles.modalCloseButton, { borderColor: modalBorderColor, backgroundColor: modalBackgroundColor }]}
|
|
1740
|
+
onPress={closeEditModal}>
|
|
1741
|
+
<Icon name="x" size={18} color={modalCloseIconColor} />
|
|
1742
|
+
</TouchableOpacity>
|
|
1743
|
+
</View>
|
|
1597
1744
|
|
|
1598
1745
|
<DefaultForm
|
|
1599
1746
|
accentColor={resolvedAccentColor}
|
|
1600
|
-
actions={
|
|
1747
|
+
actions={resolvedActions}
|
|
1601
1748
|
columns={isCreate ? columnsForTable : editableColumns}
|
|
1602
|
-
getOptionsForColumn={
|
|
1749
|
+
getOptionsForColumn={resolvedGetOptionsForColumn}
|
|
1603
1750
|
mode={formMode}
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1751
|
+
onBeforeOpen={column => loadListOptionsForColumns([column])}
|
|
1752
|
+
onCancel={closeEditModal}
|
|
1753
|
+
onSaved={(savedItem, originalRow) => {
|
|
1754
|
+
onSaved?.(savedItem, originalRow);
|
|
1755
|
+
closeEditModal();
|
|
1608
1756
|
}}
|
|
1609
1757
|
row={editingRow || {}}
|
|
1610
1758
|
storeName={storeName}
|
|
@@ -1620,18 +1768,18 @@ const DefaultTable = ({
|
|
|
1620
1768
|
|
|
1621
1769
|
return (
|
|
1622
1770
|
<Modal visible transparent animationType="fade" onRequestClose={() => setIsColumnMenuOpen(false)}>
|
|
1623
|
-
<View style={[styles.modalOverlay, { backgroundColor:
|
|
1624
|
-
<View style={[styles.modalCard, styles.columnMenuModalCard, { borderColor:
|
|
1625
|
-
<View style={[styles.modalHeader, { borderBottomColor:
|
|
1626
|
-
<Text style={[styles.modalTitle, { color:
|
|
1771
|
+
<View style={[styles.modalOverlay, { backgroundColor: modalOverlayColor }]}>
|
|
1772
|
+
<View style={[styles.modalCard, styles.columnMenuModalCard, { borderColor: modalBorderColor, backgroundColor: modalBackgroundColor }]}>
|
|
1773
|
+
<View style={[styles.modalHeader, { borderBottomColor: modalBorderColor }]}>
|
|
1774
|
+
<Text style={[styles.modalTitle, { color: modalHeaderTextColor }]} numberOfLines={1}>
|
|
1627
1775
|
Colunas
|
|
1628
1776
|
</Text>
|
|
1629
1777
|
<TouchableOpacity
|
|
1630
|
-
style={[styles.modalCloseButton, { borderColor:
|
|
1778
|
+
style={[styles.modalCloseButton, { borderColor: modalBorderColor, backgroundColor: modalBackgroundColor }]}
|
|
1631
1779
|
activeOpacity={0.82}
|
|
1632
1780
|
onPress={() => setIsColumnMenuOpen(false)}
|
|
1633
1781
|
>
|
|
1634
|
-
<Icon name="x" size={16} color={
|
|
1782
|
+
<Icon name="x" size={16} color={modalCloseIconColor} />
|
|
1635
1783
|
</TouchableOpacity>
|
|
1636
1784
|
</View>
|
|
1637
1785
|
<ScrollView style={styles.columnMenuModalBody} contentContainerStyle={styles.columnMenuModalList}>
|
|
@@ -1647,8 +1795,8 @@ const DefaultTable = ({
|
|
|
1647
1795
|
|
|
1648
1796
|
return (
|
|
1649
1797
|
<TouchableOpacity key={fieldName} style={styles.columnMenuItem} activeOpacity={0.82} onPress={() => toggleColumn(column)}>
|
|
1650
|
-
<Icon name={checked ? 'check-square' : 'square'} size={16} color={checked ?
|
|
1651
|
-
<Text style={[styles.columnMenuText, { color:
|
|
1798
|
+
<Icon name={checked ? 'check-square' : 'square'} size={16} color={checked ? checkboxSelectedMarkColor : checkboxBorderColor} />
|
|
1799
|
+
<Text style={[styles.columnMenuText, { color: modalTextColor }]} numberOfLines={1}>{label}</Text>
|
|
1652
1800
|
</TouchableOpacity>
|
|
1653
1801
|
);
|
|
1654
1802
|
})}
|
|
@@ -1660,16 +1808,16 @@ const DefaultTable = ({
|
|
|
1660
1808
|
};
|
|
1661
1809
|
|
|
1662
1810
|
return (
|
|
1663
|
-
<View style={[styles.wrap, { borderColor:
|
|
1664
|
-
<View style={[styles.toolbar, { borderBottomColor:
|
|
1665
|
-
{shouldRenderCompactToolbarTotalItems ? (
|
|
1666
|
-
<View style={styles.toolbarCompactLead}>
|
|
1667
|
-
<View style={[styles.toolbarCountPill, { backgroundColor:
|
|
1668
|
-
<Text
|
|
1669
|
-
style={[styles.toolbarCountText, { color:
|
|
1670
|
-
numberOfLines={1}
|
|
1671
|
-
adjustsFontSizeToFit
|
|
1672
|
-
minimumFontScale={0.82}
|
|
1811
|
+
<View style={[styles.wrap, { borderColor: panelBorderColor, backgroundColor: panelBackgroundColor }]} onLayout={handleLayout}>
|
|
1812
|
+
<View style={[styles.toolbar, { borderBottomColor: toolbarBorderColor, backgroundColor: toolbarBackgroundColor }]}>
|
|
1813
|
+
{shouldRenderCompactToolbarTotalItems ? (
|
|
1814
|
+
<View style={styles.toolbarCompactLead}>
|
|
1815
|
+
<View style={[styles.toolbarCountPill, { backgroundColor: toolbarCountBackgroundColor }]}>
|
|
1816
|
+
<Text
|
|
1817
|
+
style={[styles.toolbarCountText, { color: toolbarCountTextColor }]}
|
|
1818
|
+
numberOfLines={1}
|
|
1819
|
+
adjustsFontSizeToFit
|
|
1820
|
+
minimumFontScale={0.82}
|
|
1673
1821
|
>
|
|
1674
1822
|
{resolvedTotalItemsText}
|
|
1675
1823
|
</Text>
|
|
@@ -1704,50 +1852,70 @@ const DefaultTable = ({
|
|
|
1704
1852
|
/>
|
|
1705
1853
|
) : null}
|
|
1706
1854
|
{!shouldRenderCompactToolbarTotalItems ? renderToolbarActions() : null}
|
|
1707
|
-
{showColumnFiltersButton ? (
|
|
1708
|
-
<TouchableOpacity
|
|
1709
|
-
style={[
|
|
1710
|
-
styles.toolbarButton,
|
|
1711
|
-
{ borderColor:
|
|
1712
|
-
showColumnFilters
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1855
|
+
{showColumnFiltersButton ? (
|
|
1856
|
+
<TouchableOpacity
|
|
1857
|
+
style={[
|
|
1858
|
+
styles.toolbarButton,
|
|
1859
|
+
{ borderColor: tableButtonBorderColor, backgroundColor: tableButtonBackgroundColor },
|
|
1860
|
+
showColumnFilters
|
|
1861
|
+
? { backgroundColor: tableButtonPressedBackgroundColor, borderColor: tableButtonPressedBorderColor }
|
|
1862
|
+
: null,
|
|
1863
|
+
]}
|
|
1864
|
+
activeOpacity={0.82}
|
|
1865
|
+
onPress={() => setShowColumnFilters(prev => !prev)}
|
|
1866
|
+
>
|
|
1867
|
+
<Icon
|
|
1868
|
+
name="filter"
|
|
1869
|
+
size={14}
|
|
1870
|
+
color={showColumnFilters ? tableButtonPressedIconColor : tableButtonIconColor}
|
|
1871
|
+
/>
|
|
1872
|
+
{activeFilterCount > 0 ? (
|
|
1873
|
+
<Text
|
|
1874
|
+
style={[
|
|
1875
|
+
styles.toolbarBadgeText,
|
|
1876
|
+
{ color: showColumnFilters ? tableButtonPressedIconColor : tableButtonIconColor },
|
|
1877
|
+
]}>
|
|
1878
|
+
{activeFilterCount}
|
|
1879
|
+
</Text>
|
|
1880
|
+
) : null}
|
|
1881
|
+
</TouchableOpacity>
|
|
1882
|
+
) : null}
|
|
1883
|
+
<TouchableOpacity
|
|
1884
|
+
style={[
|
|
1885
|
+
styles.toolbarButton,
|
|
1886
|
+
{ borderColor: tableButtonBorderColor, backgroundColor: tableButtonBackgroundColor },
|
|
1887
|
+
effectiveViewMode !== 'table'
|
|
1888
|
+
? { backgroundColor: tableButtonPressedBackgroundColor, borderColor: tableButtonPressedBorderColor }
|
|
1889
|
+
: null,
|
|
1890
|
+
]}
|
|
1891
|
+
activeOpacity={0.82}
|
|
1892
|
+
onPress={toggleViewMode}
|
|
1893
|
+
>
|
|
1894
|
+
<Icon
|
|
1895
|
+
name={effectiveViewMode === 'table' ? 'list' : 'grid'}
|
|
1896
|
+
size={14}
|
|
1897
|
+
color={effectiveViewMode !== 'table' ? tableButtonPressedIconColor : tableButtonIconColor}
|
|
1898
|
+
/>
|
|
1899
|
+
</TouchableOpacity>
|
|
1900
|
+
<TouchableOpacity
|
|
1901
|
+
style={[styles.toolbarButton, { borderColor: tableButtonBorderColor, backgroundColor: tableButtonBackgroundColor }]}
|
|
1902
|
+
activeOpacity={0.82}
|
|
1903
|
+
onPress={() => setIsColumnMenuOpen(prev => !prev)}>
|
|
1904
|
+
<Icon name="columns" size={14} color={tableButtonTextColor} />
|
|
1905
|
+
</TouchableOpacity>
|
|
1906
|
+
{shouldRenderAddButton ? (
|
|
1907
|
+
<TouchableOpacity
|
|
1908
|
+
style={[
|
|
1909
|
+
styles.toolbarButton,
|
|
1910
|
+
styles.toolbarAddButton,
|
|
1911
|
+
{ backgroundColor: tableButtonBackgroundColor, borderColor: tableButtonBackgroundColor },
|
|
1912
|
+
]}
|
|
1913
|
+
activeOpacity={0.85}
|
|
1914
|
+
onPress={openAddForm}
|
|
1915
|
+
>
|
|
1916
|
+
<Icon name="plus" size={16} color={tableButtonTextColor} />
|
|
1917
|
+
</TouchableOpacity>
|
|
1918
|
+
) : null}
|
|
1751
1919
|
</View>
|
|
1752
1920
|
|
|
1753
1921
|
</View>
|
|
@@ -1756,7 +1924,7 @@ const DefaultTable = ({
|
|
|
1756
1924
|
<FlatList
|
|
1757
1925
|
data={sortedData}
|
|
1758
1926
|
keyExtractor={getRowKey}
|
|
1759
|
-
renderItem={({ item }) => renderCardItem(item)}
|
|
1927
|
+
renderItem={({ item, index }) => renderCardItem(item, index)}
|
|
1760
1928
|
style={styles.cardsScroll}
|
|
1761
1929
|
contentContainerStyle={styles.cardsGrid}
|
|
1762
1930
|
ListEmptyComponent={renderEmptyState(false)}
|
|
@@ -1839,54 +2007,60 @@ const DefaultTable = ({
|
|
|
1839
2007
|
</ScrollView>
|
|
1840
2008
|
)}
|
|
1841
2009
|
|
|
1842
|
-
{renderLoadingOverlay()}
|
|
1843
|
-
|
|
1844
|
-
{
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
2010
|
+
{renderLoadingOverlay()}
|
|
2011
|
+
|
|
2012
|
+
{footerComponent ? (
|
|
2013
|
+
React.isValidElement(footerComponent) ? (
|
|
2014
|
+
footerComponent
|
|
2015
|
+
) : (
|
|
2016
|
+
React.createElement(footerComponent, footerProps)
|
|
2017
|
+
)
|
|
2018
|
+
) : shouldRenderFooterBar ? (
|
|
2019
|
+
<View style={[styles.footerBar, { backgroundColor: tableSurfaceColor, borderTopColor: tableBorderColor }]}>
|
|
2020
|
+
{summaryEntries.length > 0 ? (
|
|
2021
|
+
<View style={styles.footerSummaryList}>
|
|
2022
|
+
{summaryEntries.map(entry => (
|
|
2023
|
+
<View key={entry.key} style={styles.footerSummaryItem}>
|
|
2024
|
+
<Text style={[styles.footerSummaryLabel, { color: tableMutedColor }]} numberOfLines={1}>
|
|
2025
|
+
{entry.label}
|
|
2026
|
+
</Text>
|
|
2027
|
+
<Text
|
|
2028
|
+
style={[
|
|
2029
|
+
styles.footerSummaryValue,
|
|
2030
|
+
entry.path?.[0] === 'sum' || isMoneySummaryPath(entry.path)
|
|
2031
|
+
? { color: resolvedAccentColor }
|
|
2032
|
+
: { color: tableTextColor },
|
|
2033
|
+
]}
|
|
2034
|
+
numberOfLines={1}
|
|
2035
|
+
adjustsFontSizeToFit
|
|
2036
|
+
minimumFontScale={0.78}
|
|
2037
|
+
>
|
|
1864
2038
|
{formatSummaryValue({
|
|
1865
2039
|
column: entry.column,
|
|
1866
2040
|
columns: columnsForTable,
|
|
1867
2041
|
path: entry.path,
|
|
1868
2042
|
storeName,
|
|
1869
2043
|
value: entry.value,
|
|
1870
|
-
})}
|
|
1871
|
-
</Text>
|
|
1872
|
-
</View>
|
|
1873
|
-
))}
|
|
1874
|
-
</View>
|
|
1875
|
-
) : null}
|
|
1876
|
-
{shouldRenderFooterTotalItems && !shouldRenderCompactToolbarTotalItems ? (
|
|
1877
|
-
<View style={[styles.footerCountPill, { backgroundColor:
|
|
1878
|
-
<Text
|
|
1879
|
-
style={[styles.footerCountText, { color:
|
|
1880
|
-
numberOfLines={1}
|
|
1881
|
-
adjustsFontSizeToFit
|
|
1882
|
-
minimumFontScale={0.82}
|
|
1883
|
-
>
|
|
1884
|
-
{resolvedTotalItemsText}
|
|
1885
|
-
</Text>
|
|
1886
|
-
</View>
|
|
1887
|
-
) : null}
|
|
1888
|
-
</View>
|
|
1889
|
-
) : null}
|
|
2044
|
+
})}
|
|
2045
|
+
</Text>
|
|
2046
|
+
</View>
|
|
2047
|
+
))}
|
|
2048
|
+
</View>
|
|
2049
|
+
) : null}
|
|
2050
|
+
{shouldRenderFooterTotalItems && !shouldRenderCompactToolbarTotalItems ? (
|
|
2051
|
+
<View style={[styles.footerCountPill, { backgroundColor: toolbarCountBackgroundColor }]}>
|
|
2052
|
+
<Text
|
|
2053
|
+
style={[styles.footerCountText, { color: toolbarCountTextColor }]}
|
|
2054
|
+
numberOfLines={1}
|
|
2055
|
+
adjustsFontSizeToFit
|
|
2056
|
+
minimumFontScale={0.82}
|
|
2057
|
+
>
|
|
2058
|
+
{resolvedTotalItemsText}
|
|
2059
|
+
</Text>
|
|
2060
|
+
</View>
|
|
2061
|
+
) : null}
|
|
2062
|
+
</View>
|
|
2063
|
+
) : null}
|
|
1890
2064
|
|
|
1891
2065
|
{renderColumnMenuModal()}
|
|
1892
2066
|
{renderEditModal()}
|