Skip to content

Commit 1ae187a

Browse files
committed
feat: passing Dataset<T> to FSortFilterDataset or FPaginateDataset returns Dataset<T> (refs SFKUI-7348)
1 parent aead241 commit 1ae187a

File tree

5 files changed

+42
-29
lines changed

5 files changed

+42
-29
lines changed

etc/vue.api.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ import { Slots } from 'vue';
5050
import { StackHandle } from '@fkui/logic';
5151
import { TranslateFunction } from '@fkui/logic';
5252
import { UnwrapRef } from 'vue';
53-
import { UnwrapRefSimple } from '@vue/reactivity';
5453
import { ValidatableHTMLElement } from '@fkui/logic';
5554
import { ValidationConfigUpdateDetail } from '@fkui/logic';
5655
import { ValidatorConfigs } from '@fkui/logic';

packages/vue/src/components/FPaginateDataset/FPaginateDataset.vue

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
<script setup lang="ts" generic="T">
2-
import { computed, onMounted, provide, ref, watch } from "vue";
1+
<script setup lang="ts" generic="T, TArray extends Dataset<T> | T[] = Dataset<T> | T[]">
2+
import { type Ref, computed, onMounted, provide, ref, watch } from "vue";
3+
import { type Dataset } from "../../utils";
34
import { type FPaginateDatasetPageEventDetail } from "../FPaginator";
45
import { paginateDatasetKey } from "./provide";
56
67
// Defines component props
78
const {
8-
items = [],
9+
items = [] as unknown as TInfered,
910
itemsPerPage = 10,
1011
itemsLength = 0,
1112
fetchData = () => null,
1213
} = defineProps<{
1314
/**
1415
* The items to be used. The items will be used in the given array order.
1516
*/
16-
items?: T[];
17+
items?: TInfered;
1718
1819
/**
1920
* The number of items per page (at most).
@@ -33,11 +34,13 @@ const {
3334
* @param firstItemIndex - The index of the first item on the page.
3435
* @param lastItemIndex - The index of the last item on the page.
3536
*/
36-
fetchData?(firstItemIndex: number, lastItemIndex: number): T[] | Promise<T[]>;
37+
fetchData?(firstItemIndex: number, lastItemIndex: number): TInfered | Promise<TInfered>;
3738
}>();
3839
40+
type TInfered = TArray extends Dataset<infer U> ? Dataset<U> : TArray;
41+
3942
// References fetched data
40-
const fetchedData = ref(null as T[] | null);
43+
const fetchedData = ref(null as TInfered | null) as Ref<TInfered | null>;
4144
4245
// References status of ongoing data fetching
4346
const dataFetchingInProgress = ref(false);
@@ -50,7 +53,12 @@ const firstItemIndex = computed(() => Math.max(0, itemsPerPage * (currentPage.va
5053
const lastItemIndex = computed(() => Math.min(itemsPerPage * currentPage.value, numberOfItems.value));
5154
5255
// Computes array of items on current page
53-
const currentPageItems = computed(() => fetchedData.value ?? items.slice(firstItemIndex.value, lastItemIndex.value));
56+
const currentPageItems = computed<TInfered>((): TInfered => {
57+
if (fetchedData.value) {
58+
return fetchedData.value;
59+
}
60+
return items.slice(firstItemIndex.value, lastItemIndex.value) as TInfered;
61+
});
5462
5563
// Computes number of items on current page
5664
const currentPageItemLength = computed(() => currentPageItems.value.length);

packages/vue/src/components/FSortFilterDataset/FSortFilterDataset.vue

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
<script setup lang="ts" generic="T">
1+
<script setup lang="ts" generic="T, TArray extends Dataset<T> | T[] = Dataset<T> | T[]">
22
import { type Ref, nextTick, onMounted, provide, useTemplateRef, watch } from "vue";
33
import { TranslationService, alertScreenReader, debounce } from "@fkui/logic";
44
import { IFlex, IFlexItem } from "../../internal-components/IFlex";
55
import { useTranslate } from "../../plugins";
6-
import { getHTMLElementFromVueRef } from "../../utils";
6+
import { type Dataset, getHTMLElementFromVueRef } from "../../utils";
77
import { FIcon } from "../FIcon";
88
import { FSelectField } from "../FSelectField";
99
import { FTextField } from "../FTextField";
@@ -14,11 +14,11 @@ import {
1414
import { type SortOrder } from "./sort-order";
1515
import { useSortFilterDataset } from "./use-sort-filter-dataset";
1616
17-
export interface FSortFilterDatasetProps<T> {
17+
export interface FSortFilterDatasetProps<TArray> {
1818
/**
1919
* The data that you wish to sort or filter.
2020
*/
21-
data: T[];
21+
data: TArray;
2222
/**
2323
* All the attributes you want to enable sorting for and the corresponding name to display in the dropdown.
2424
* Structured as `{attributeName: "Name for dropdown", secondAttributeName: "Name for dropdown"}`
@@ -52,6 +52,8 @@ export interface FSortFilterDatasetProps<T> {
5252
filterAttributes?: PropertyKey[];
5353
}
5454
55+
type TInfered = TArray extends Dataset<infer U> ? Dataset<U> : TArray;
56+
5557
const {
5658
data,
5759
sortableAttributes,
@@ -64,15 +66,15 @@ const {
6466
/* eslint-disable-next-line vue/no-boolean-default -- technical debt, boolean attributes should be opt-in not opt-out */
6567
defaultSortAscending = true,
6668
filterAttributes = undefined,
67-
} = defineProps<FSortFilterDatasetProps<T>>();
69+
} = defineProps<FSortFilterDatasetProps<TInfered>>();
6870
6971
const emit = defineEmits<{
7072
/**
7173
* Emitted when the data is sorted.
7274
*
7375
* @arg items - The sorted data.
7476
*/
75-
datasetSorted: [items: T[]];
77+
datasetSorted: [items: TInfered];
7678
7779
/**
7880
* Emits the used sorting attributes.
@@ -94,7 +96,7 @@ const {
9496
sortOrders,
9597
onUserChangeSortAttribute,
9698
onApiChangeSortAttribute,
97-
} = useSortFilterDataset(
99+
} = useSortFilterDataset<T, TInfered>(
98100
() => data,
99101
() => sortableAttributes,
100102
() => filterAttributes,

packages/vue/src/components/FSortFilterDataset/FSortFilterFilter.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { isSet } from "@fkui/logic";
2+
import { type Dataset } from "../../utils";
23

34
function includesAllSearchTerms(
45
item: Record<PropertyKey, string | number | undefined>,
@@ -23,11 +24,11 @@ function includesAllSearchTerms(
2324
return true;
2425
}
2526

26-
export function filter<T>(
27-
list: T[],
27+
export function filter<T, TArray extends Dataset<T> | T[]>(
28+
list: TArray,
2829
filterAttributes: PropertyKey[],
2930
searchString: string,
30-
): T[] {
31+
): TArray {
3132
searchString = searchString.trim();
3233
if (searchString.trim() === "") {
3334
return list;
@@ -43,5 +44,5 @@ export function filter<T>(
4344
filterAttributes,
4445
searchTerms,
4546
),
46-
);
47+
) as TArray;
4748
}

packages/vue/src/components/FSortFilterDataset/use-sort-filter-dataset.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
watch,
88
} from "vue";
99
import { useTranslate } from "../../plugins";
10+
import { type Dataset } from "../../utils";
1011
import { filter } from "./FSortFilterFilter";
1112
import { sort } from "./FSortFilterSorter";
1213
import { type SortOrder } from "./sort-order";
@@ -84,24 +85,24 @@ function normalizeFilterAttributes(
8485
return filterAttributes;
8586
}
8687

87-
function sortFilterData<T>(
88-
data: T[],
88+
function sortFilterData<T, TArray extends Dataset<T> | T[]>(
89+
data: TArray,
8990
filterAttributes: PropertyKey[],
9091
searchString: string,
9192
sortAttribute: SortableAttribute,
92-
): T[] {
93+
): TArray {
9394
const filteredData = filter(data, filterAttributes, searchString);
9495

9596
return sort(filteredData, {
9697
attribute: sortAttribute.attribute as keyof T | "",
9798
ascending: sortAttribute.ascending,
98-
});
99+
}) as TArray;
99100
}
100101

101-
export interface SortFilterDatasetState<T> {
102+
export interface SortFilterDatasetState<T, TArray extends Dataset<T> | T[]> {
102103
searchString: Ref<string>;
103104
sortAttribute: Ref<SortOrder>;
104-
sortFilterResult: Ref<T[]>;
105+
sortFilterResult: Ref<TArray>;
105106
showClearButton: Ref<boolean>;
106107
defaultSortValue: SortOrder;
107108
sortableKeys: Ref<Array<string | symbol>>;
@@ -114,18 +115,20 @@ export interface SortFilterDatasetState<T> {
114115
): void;
115116
}
116117

117-
export function useSortFilterDataset<T>(
118-
data: MaybeRefOrGetter<T[]>,
118+
export function useSortFilterDataset<T, TArray extends Dataset<T> | T[]>(
119+
data: MaybeRefOrGetter<TArray>,
119120
sortableAttributes: MaybeRefOrGetter<
120121
Record<PropertyKey, string | Readonly<Ref<string>>>
121122
>,
122123
filterAttributes: MaybeRefOrGetter<PropertyKey[] | undefined>,
123124
defaultSortAttribute: PropertyKey,
124125
defaultSortAscending: boolean,
125-
): SortFilterDatasetState<T> {
126+
): SortFilterDatasetState<T, TArray> {
126127
const searchString = ref("");
127128
const sortAttribute = ref<SortOrder>({ ...defaultSortValue });
128-
const sortFilterResult: Ref<T[]> = ref([]);
129+
const sortFilterResult = ref<TArray>(
130+
[] as unknown as TArray,
131+
) as Ref<TArray>;
129132
const useDefaultSortOrder = ref(true);
130133

131134
/* all enumerable keys from sortableAttributes */

0 commit comments

Comments
 (0)