@bimdata/bcf-components 6.0.0-rc.8 → 6.0.0

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.
Files changed (65) hide show
  1. package/README.md +0 -6
  2. package/package.json +15 -20
  3. package/src/components/bcf-filters/BcfFilters.scss +67 -0
  4. package/src/components/bcf-filters/BcfFilters.vue +228 -0
  5. package/src/components/bcf-settings/BcfSettings.scss +28 -0
  6. package/src/components/bcf-settings/BcfSettings.vue +117 -0
  7. package/src/components/bcf-settings/setting-card/SettingCard.scss +59 -0
  8. package/src/components/bcf-settings/setting-card/SettingCard.vue +140 -0
  9. package/src/components/bcf-settings/setting-card/SettingCardItem.scss +48 -0
  10. package/src/components/bcf-settings/setting-card/SettingCardItem.vue +151 -0
  11. package/src/components/bcf-statistics/BcfStatistics.scss +56 -0
  12. package/src/components/bcf-statistics/BcfStatistics.vue +112 -0
  13. package/src/components/bcf-topic-card/BcfTopicCard.scss +96 -0
  14. package/src/components/bcf-topic-card/BcfTopicCard.vue +150 -0
  15. package/src/components/bcf-topic-card/BcfTopicDefaultImage.vue +90 -0
  16. package/src/components/bcf-topic-creation-card/BcfTopicCreationCard.scss +15 -0
  17. package/src/components/bcf-topic-creation-card/BcfTopicCreationCard.vue +37 -0
  18. package/src/components/bcf-topic-creation-card/BcfTopicCreationCardImage.vue +55 -0
  19. package/src/components/bcf-topic-form/BcfTopicForm.scss +124 -0
  20. package/src/components/bcf-topic-form/BcfTopicForm.vue +541 -0
  21. package/src/components/bcf-topic-form/bcf-topic-images/BcfTopicImages.scss +88 -0
  22. package/src/components/bcf-topic-form/bcf-topic-images/BcfTopicImages.vue +101 -0
  23. package/src/components/bcf-topic-form/bcf-topic-snapshots/BcfTopicSnapshots.scss +50 -0
  24. package/src/components/bcf-topic-form/bcf-topic-snapshots/BcfTopicSnapshots.vue +71 -0
  25. package/src/components/bcf-topic-form/bcf-topic-snapshots-actions/BcfTopicSnapshotsActions.scss +9 -0
  26. package/src/components/bcf-topic-form/bcf-topic-snapshots-actions/BcfTopicSnapshotsActions.vue +69 -0
  27. package/src/components/bcf-topic-overview/BcfTopicOverview.scss +94 -0
  28. package/src/components/bcf-topic-overview/BcfTopicOverview.vue +350 -0
  29. package/src/components/bcf-topic-overview/bcf-topic-comments/BcfTopicComments.scss +39 -0
  30. package/src/components/bcf-topic-overview/bcf-topic-comments/BcfTopicComments.vue +268 -0
  31. package/src/components/bcf-topic-overview/bcf-topic-comments/topic-comment/TopicComment.scss +79 -0
  32. package/src/components/bcf-topic-overview/bcf-topic-comments/topic-comment/TopicComment.vue +357 -0
  33. package/src/components/bcf-topic-overview/bcf-topic-viewpoints/BcfTopicViewpoints.scss +73 -0
  34. package/src/components/bcf-topic-overview/bcf-topic-viewpoints/BcfTopicViewpoints.vue +84 -0
  35. package/src/components/bcf-topics-table/BcfTopicsTable.vue +148 -0
  36. package/src/components/bcf-topics-table/bcf-topic-actions-cell/BcfTopicActionsCell.vue +43 -0
  37. package/src/components/bcf-topics-table/bcf-topic-index-cell/BcfTopicIndexCell.vue +55 -0
  38. package/src/components/bcf-topics-table/bcf-topic-priority-cell/BcfTopicPriorityCell.vue +47 -0
  39. package/src/components/bcf-topics-table/bcf-topic-status-cell/BcfTopicStatusCell.vue +52 -0
  40. package/src/components/bcf-topics-table/columns.js +38 -0
  41. package/src/components/user-avatar/UserAvatar.scss +30 -0
  42. package/src/components/user-avatar/UserAvatar.vue +66 -0
  43. package/src/composables/filter.js +58 -0
  44. package/src/composables/search.js +42 -0
  45. package/src/composables/sort.js +64 -0
  46. package/src/config.js +87 -0
  47. package/{dist → src}/i18n/lang/en.json +3 -1
  48. package/{dist → src}/i18n/lang/fr.json +5 -1
  49. package/src/index.js +59 -0
  50. package/src/service.js +206 -0
  51. package/src/utils/browser.js +12 -0
  52. package/src/utils/download.js +15 -0
  53. package/src/utils/extensions.js +14 -0
  54. package/src/utils/topic.js +23 -0
  55. package/src/utils/viewer.js +21 -0
  56. package/src/utils/viewpoints.js +28 -0
  57. package/vue3-plugin.js +4 -5
  58. package/dist/bcf-components.mjs +0 -10311
  59. package/dist/style.css +0 -1
  60. /package/{dist → src}/i18n/index.js +0 -0
  61. /package/{dist → src}/i18n/lang/de.json +0 -0
  62. /package/{dist → src}/i18n/lang/es.json +0 -0
  63. /package/{dist → src}/i18n/lang/it.json +0 -0
  64. /package/{dist → src}/i18n/lang/nl.json +0 -0
  65. /package/{dist → src}/i18n/lang/no.json +0 -0
@@ -0,0 +1,148 @@
1
+ <template>
2
+ <BIMDataTable
3
+ class="bcf-topics-table"
4
+ tableLayout="fixed"
5
+ :columns="
6
+ displayedColumns
7
+ .map(col => ({
8
+ ...col,
9
+ label: col.label || $t(`BcfComponents.BcfTopicsTable.headers.${col.id}`)
10
+ }))
11
+ "
12
+ :rows="topics"
13
+ rowKey="guid"
14
+ :paginated="paginated"
15
+ :perPage="perPage"
16
+ :rowHeight="42"
17
+ :selectable="selectable"
18
+ :selection="selection"
19
+ @update:selection="$emit('update:selection', $event)"
20
+ >
21
+ <template #cell-index="{ row: topic }">
22
+ <BcfTopicIndexCell
23
+ :detailedExtensions="detailedExtensions"
24
+ :topic="topic"
25
+ />
26
+ </template>
27
+ <template #cell-priority="{ row: topic }">
28
+ <BcfTopicPriorityCell
29
+ :detailedExtensions="detailedExtensions"
30
+ :topic="topic"
31
+ />
32
+ </template>
33
+ <template #cell-status="{ row: topic }">
34
+ <BcfTopicStatusCell
35
+ v-if="topic.topic_status"
36
+ :detailedExtensions="detailedExtensions"
37
+ :topic="topic"
38
+ />
39
+ </template>
40
+ <template #cell-title="{ row: topic }">
41
+ <BIMDataTextbox maxWidth="100%" :text="topic.title" />
42
+ </template>
43
+ <template #cell-creator="{ row: { creator, creation_author } }">
44
+ <BIMDataTooltip :text="creation_author">
45
+ <UserAvatar
46
+ :user="creator || {}"
47
+ :size="30"
48
+ color="silver-light"
49
+ style="margin: auto"
50
+ />
51
+ </BIMDataTooltip>
52
+ </template>
53
+ <template #cell-date="{ row: topic }">
54
+ {{ toShortDateFormat(topic.creation_date) }}
55
+ </template>
56
+ <template #cell-actions="{ row: topic }">
57
+ <BcfTopicActionsCell
58
+ :topic="topic"
59
+ @open-topic="$emit('open-topic', $event)"
60
+ />
61
+ </template>
62
+ </BIMDataTable>
63
+ </template>
64
+
65
+ <script>
66
+ import { computed } from "vue";
67
+ import columnsDef from "./columns.js";
68
+ // Components
69
+ import BIMDataTable from "@bimdata/design-system/src/BIMDataComponents/BIMDataTable/BIMDataTable.vue";
70
+ import BIMDataTextbox from "@bimdata/design-system/src/BIMDataComponents/BIMDataTextbox/BIMDataTextbox.vue";
71
+ import BIMDataTooltip from "@bimdata/design-system/src/BIMDataComponents/BIMDataTooltip/BIMDataTooltip.vue";
72
+ import BcfTopicActionsCell from "./bcf-topic-actions-cell/BcfTopicActionsCell.vue";
73
+ import BcfTopicIndexCell from "./bcf-topic-index-cell/BcfTopicIndexCell.vue";
74
+ import BcfTopicPriorityCell from "./bcf-topic-priority-cell/BcfTopicPriorityCell.vue";
75
+ import BcfTopicStatusCell from "./bcf-topic-status-cell/BcfTopicStatusCell.vue";
76
+
77
+ // TODO: should be imported from DS
78
+ import UserAvatar from "../user-avatar/UserAvatar.vue";
79
+
80
+ export default {
81
+ components: {
82
+ BcfTopicActionsCell,
83
+ BcfTopicIndexCell,
84
+ BcfTopicPriorityCell,
85
+ BcfTopicStatusCell,
86
+ BIMDataTable,
87
+ BIMDataTextbox,
88
+ BIMDataTooltip,
89
+ UserAvatar
90
+ },
91
+ props: {
92
+ detailedExtensions: {
93
+ type: Object,
94
+ required: true
95
+ },
96
+ topics: {
97
+ type: Array,
98
+ required: true
99
+ },
100
+ paginated: {
101
+ type: Boolean,
102
+ default: false
103
+ },
104
+ perPage: {
105
+ type: Number,
106
+ default: 10
107
+ },
108
+ columns: {
109
+ type: Array
110
+ },
111
+ selectable: {
112
+ type: Boolean,
113
+ default: false
114
+ },
115
+ selection: {
116
+ type: Map,
117
+ default: () => new Map(),
118
+ },
119
+ },
120
+ emits: [
121
+ "open-topic",
122
+ "update:selection",
123
+ ],
124
+ setup(props) {
125
+ const displayedColumns = computed(() =>
126
+ props.columns && props.columns.length > 0
127
+ ? columnsDef.filter(c => props.columns.includes(c.id))
128
+ : columnsDef
129
+ );
130
+
131
+ const toShortDateFormat = (date) => {
132
+ if (!date) return "";
133
+
134
+ const d = date.toISOString().split('T')[0].split('-').reverse();
135
+ d[2] = d[2].slice(-2);
136
+
137
+ return d.join("/");
138
+ };
139
+
140
+ return {
141
+ // References
142
+ displayedColumns,
143
+ // Methods
144
+ toShortDateFormat,
145
+ };
146
+ }
147
+ };
148
+ </script>
@@ -0,0 +1,43 @@
1
+ <template>
2
+ <div class="bcf-topic-actions-cell">
3
+ <BIMDataButton
4
+ color="primary"
5
+ outline
6
+ radius
7
+ icon
8
+ @click="$emit('open-topic', topic)"
9
+ >
10
+ <BIMDataIconShow size="xs" />
11
+ </BIMDataButton>
12
+ </div>
13
+ </template>
14
+
15
+ <script>
16
+ // Components
17
+ import BIMDataButton from "@bimdata/design-system/src/BIMDataComponents/BIMDataButton/BIMDataButton.vue";
18
+ import BIMDataIconShow from "@bimdata/design-system/src/BIMDataComponents/BIMDataIcon/BIMDataIconStandalone/BIMDataIconShow.vue";
19
+
20
+ export default {
21
+ components: {
22
+ BIMDataButton,
23
+ BIMDataIconShow,
24
+ },
25
+ props: {
26
+ topic: {
27
+ type: Object,
28
+ required: true
29
+ }
30
+ },
31
+ emits: [
32
+ "open-topic"
33
+ ],
34
+ };
35
+ </script>
36
+
37
+ <style scoped lang="scss">
38
+ .bcf-topic-actions-cell {
39
+ .bimdata-btn {
40
+ margin: auto;
41
+ }
42
+ }
43
+ </style>
@@ -0,0 +1,55 @@
1
+ <template>
2
+ <div class="bcf-topic-index-cell">
3
+ <span
4
+ class="left-stripe"
5
+ :style="{ backgroundColor: `#${priorityColor}` }"
6
+ ></span>
7
+ <span class="index">
8
+ {{ topic.index }}
9
+ </span>
10
+ </div>
11
+ </template>
12
+
13
+ <script>
14
+ import { computed } from "vue";
15
+ import { getPriorityColor } from "../../../utils/topic.js";
16
+
17
+ export default {
18
+ props: {
19
+ detailedExtensions: {
20
+ type: Object,
21
+ required: true,
22
+ },
23
+ topic: {
24
+ type: Object,
25
+ required: true,
26
+ },
27
+ },
28
+ setup(props) {
29
+ const priorityColor = computed(
30
+ () => getPriorityColor(props.topic, props.detailedExtensions)
31
+ );
32
+
33
+ return {
34
+ // References
35
+ priorityColor,
36
+ };
37
+ }
38
+ };
39
+ </script>
40
+
41
+ <style scoped lang="scss">
42
+ .bcf-topic-index-cell {
43
+ position: relative;
44
+ display: flex;
45
+ justify-content: center;
46
+ align-items: center;
47
+
48
+ .left-stripe {
49
+ position: absolute;
50
+ left: calc(0px - var(--spacing-unit));
51
+ width: 10px;
52
+ height: 42px;
53
+ }
54
+ }
55
+ </style>
@@ -0,0 +1,47 @@
1
+ <template>
2
+ <span
3
+ class="bcf-topic-priority-cell"
4
+ :style="{ color: `#${priorityColor}` }"
5
+ >
6
+ {{ topic.priority || $t("BcfComponents.BcfTopicPriorityCell.noPriority") }}
7
+ </span>
8
+ </template>
9
+
10
+ <script>
11
+ import { computed } from "vue";
12
+ import { getPriorityColor } from "../../../utils/topic.js";
13
+
14
+ export default {
15
+ props: {
16
+ detailedExtensions: {
17
+ type: Object,
18
+ required: true
19
+ },
20
+ topic: {
21
+ type: Object,
22
+ required: true
23
+ },
24
+ },
25
+ setup(props) {
26
+ const priorityColor = computed(
27
+ () => getPriorityColor(props.topic, props.detailedExtensions)
28
+ );
29
+
30
+ return {
31
+ // References
32
+ priorityColor,
33
+ };
34
+ }
35
+ };
36
+ </script>
37
+
38
+ <style scoped lang="scss">
39
+ .bcf-topic-priority-cell {
40
+ height: 42px;
41
+ padding: 0 calc(var(--spacing-unit) / 2);
42
+ display: flex;
43
+ justify-content: center;
44
+ align-items: center;
45
+ font-weight: bold;
46
+ }
47
+ </style>
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <span
3
+ class="bcf-topic-status-cell"
4
+ :style="{
5
+ backgroundColor: `#${statusColor}`,
6
+ color: adjustTextColor(statusColor, '#ffffff', 'var(--color-text)')
7
+ }"
8
+ >
9
+ {{ topic.topic_status }}
10
+ </span>
11
+ </template>
12
+
13
+ <script>
14
+ import { adjustTextColor } from "@bimdata/design-system/src/BIMDataComponents/BIMDataColorSelector/colors.js";
15
+ import { computed } from "vue";
16
+ import { getStatusColor } from "../../../utils/topic.js";
17
+
18
+ export default {
19
+ props: {
20
+ detailedExtensions: {
21
+ type: Object,
22
+ required: true
23
+ },
24
+ topic: {
25
+ type: Object,
26
+ required: true
27
+ },
28
+ },
29
+ setup(props) {
30
+ const statusColor = computed(
31
+ () => getStatusColor(props.topic, props.detailedExtensions)
32
+ );
33
+
34
+ return {
35
+ // References
36
+ statusColor,
37
+ // Methods
38
+ adjustTextColor,
39
+ };
40
+ }
41
+ };
42
+ </script>
43
+
44
+ <style scoped lang="scss">
45
+ .bcf-topic-status-cell {
46
+ height: 42px;
47
+ padding: 0 calc(var(--spacing-unit) / 2);
48
+ display: flex;
49
+ justify-content: center;
50
+ align-items: center;
51
+ }
52
+ </style>
@@ -0,0 +1,38 @@
1
+ export default [
2
+ {
3
+ id: "index",
4
+ label: "#",
5
+ width: "60px",
6
+ align: "center"
7
+ },
8
+ {
9
+ id: "priority",
10
+ width: "120px",
11
+ align: "center"
12
+ },
13
+ {
14
+ id: "status",
15
+ width: "100px",
16
+ align: "center"
17
+ },
18
+ {
19
+ id: "title",
20
+ align: "left"
21
+ },
22
+ {
23
+ id: "creator",
24
+ width: "60px",
25
+ align: "center"
26
+ },
27
+ {
28
+ id: "date",
29
+ width: "90px",
30
+ align: "center"
31
+ },
32
+ {
33
+ id: "actions",
34
+ label: " ",
35
+ width: "60px",
36
+ align: "center"
37
+ }
38
+ ];
@@ -0,0 +1,30 @@
1
+ .user-avatar {
2
+ min-width: 32px;
3
+ min-height: 32px;
4
+
5
+ display: flex;
6
+ justify-content: center;
7
+ align-items: center;
8
+ border-radius: 50%;
9
+ overflow: hidden;
10
+
11
+ img {
12
+ width: 100%;
13
+ height: 100%;
14
+ }
15
+
16
+ &--primary {
17
+ background-color: var(--color-primary);
18
+ color: var(--color-silver-light);
19
+ }
20
+
21
+ &--secondary {
22
+ background-color: var(--color-secondary);
23
+ color: var(--color-primary);
24
+ }
25
+
26
+ &--silver-light {
27
+ background-color: var(--color-silver-light);
28
+ color: var(--color-primary);
29
+ }
30
+ }
@@ -0,0 +1,66 @@
1
+ <template>
2
+ <div
3
+ class="user-avatar"
4
+ :class="`user-avatar--${user.profile_picture ? 'silver-light' : color}`"
5
+ :style="{
6
+ width: `${size}px`,
7
+ height: `${size}px`,
8
+ fontSize: `${initialsSize ? initialsSize : +size * 0.382}px`,
9
+ }"
10
+ >
11
+ <template v-if="user.profile_picture">
12
+ <img :src="user.profile_picture" />
13
+ </template>
14
+ <template v-else-if="initials">
15
+ {{ initials }}
16
+ </template>
17
+ <template v-else>
18
+ <BIMDataIconUser size="xs" />
19
+ </template>
20
+ </div>
21
+ </template>
22
+
23
+ <script>
24
+ import { computed } from "vue";
25
+
26
+ import BIMDataIconUser from "@bimdata/design-system/src/BIMDataComponents/BIMDataIcon/BIMDataIconStandalone/BIMDataIconUser.vue";
27
+
28
+ export default {
29
+ components: {
30
+ BIMDataIconUser,
31
+ },
32
+ props: {
33
+ user: {
34
+ type: Object,
35
+ required: true,
36
+ },
37
+ size: {
38
+ type: [Number, String],
39
+ default: 32,
40
+ validate: (value) => value >= 32,
41
+ },
42
+ initialsSize: {
43
+ type: [Number, String],
44
+ },
45
+ color: {
46
+ type: String,
47
+ default: "primary",
48
+ validate: (value) => ["primary", "secondary", "silver-light"].includes(value),
49
+ },
50
+ },
51
+ setup(props) {
52
+ const initials = computed(() =>
53
+ (
54
+ `${(props.user.firstname && props.user.firstname[0]) || ""}` +
55
+ `${(props.user.lastname && props.user.lastname[0]) || ""}`
56
+ ).toUpperCase()
57
+ );
58
+
59
+ return {
60
+ initials,
61
+ };
62
+ },
63
+ };
64
+ </script>
65
+
66
+ <style scoped lang="scss" src="./UserAvatar.scss"></style>
@@ -0,0 +1,58 @@
1
+ import { computed, reactive } from "vue";
2
+
3
+ const EMPTY_FILTERS = {
4
+ priorities: [],
5
+ statuses: [],
6
+ users: [],
7
+ creators: [],
8
+ labels: [],
9
+ startDate: null,
10
+ endDate: null,
11
+ };
12
+
13
+ function useBcfFilter(topics) {
14
+ const filters = reactive({ ...EMPTY_FILTERS });
15
+
16
+ const filteredTopics = computed(() => {
17
+ let list = topics.value;
18
+ if (filters.priorities.length > 0) {
19
+ list = list.filter(t => filters.priorities.includes(t.priority));
20
+ }
21
+ if (filters.statuses.length > 0) {
22
+ list = list.filter(t => filters.statuses.includes(t.topic_status));
23
+ }
24
+ if (filters.users.length > 0) {
25
+ list = list.filter(t => filters.users.includes(t.assigned_to));
26
+ }
27
+ if (filters.creators.length > 0) {
28
+ list = list.filter(t => filters.creators.includes(t.creation_author));
29
+ }
30
+ if (filters.labels.length > 0) {
31
+ list = list.filter(t => filters.labels.some(l => t.labels.includes(l)));
32
+ }
33
+ if (filters.startDate && filters.endDate) {
34
+ list = list.filter(t => (
35
+ t.creation_date >= filters.startDate &&
36
+ t.creation_date <= filters.endDate
37
+ ));
38
+ }
39
+ return list;
40
+ });
41
+
42
+ function apply(f) {
43
+ Object.assign(filters, f);
44
+ }
45
+
46
+ function reset() {
47
+ apply(EMPTY_FILTERS);
48
+ }
49
+
50
+ return {
51
+ filters,
52
+ filteredTopics,
53
+ apply,
54
+ reset,
55
+ };
56
+ }
57
+
58
+ export { useBcfFilter };
@@ -0,0 +1,42 @@
1
+ import { ref, watch } from "vue";
2
+
3
+ const searchFields = [
4
+ "title",
5
+ "topic_type",
6
+ "priority",
7
+ "topic_status",
8
+ "stage",
9
+ "creation_author",
10
+ "modified_author",
11
+ "assigned_to",
12
+ "description",
13
+ ];
14
+
15
+ function useBcfSearch(topics) {
16
+ const searchText = ref("");
17
+ const filteredTopics = ref([]);
18
+
19
+ watch(
20
+ [topics, searchText],
21
+ () => {
22
+ if (searchText.value) {
23
+ const lowerCaseSearchText = searchText.value.toLowerCase();
24
+ filteredTopics.value = topics.value.filter(topic =>
25
+ searchFields.some(field =>
26
+ (topic[field] || "").toLowerCase().includes(lowerCaseSearchText)
27
+ )
28
+ );
29
+ } else {
30
+ filteredTopics.value = topics.value;
31
+ }
32
+ },
33
+ { immediate: true }
34
+ );
35
+
36
+ return {
37
+ searchText,
38
+ filteredTopics,
39
+ };
40
+ }
41
+
42
+ export { useBcfSearch };
@@ -0,0 +1,64 @@
1
+ import { ref } from "vue";
2
+
3
+ function useListSort(list, mapper = elem => elem) {
4
+ const initialList = ref(list);
5
+
6
+ const sort = (order = "asc") => {
7
+ const sortedList = initialList.value
8
+ .slice()
9
+ .sort((a, b) => (mapper(a) < mapper(b) ? -1 : 1));
10
+ if (order === "desc") {
11
+ sortedList.reverse();
12
+ }
13
+ initialList.value = sortedList;
14
+ };
15
+
16
+ const sortOrder = ref("none");
17
+ const sortToggle = () => {
18
+ sortOrder.value = sortOrder.value === "asc" ? "desc" : "asc";
19
+ sort(sortOrder.value);
20
+ };
21
+
22
+ return {
23
+ sortOrder,
24
+ sortToggle
25
+ };
26
+ }
27
+
28
+ function useBcfSort(topics) {
29
+ const { sortToggle: sortToggleIndex, sortOrder: sortOrderIndex } =
30
+ useListSort(topics, topic => topic.index);
31
+
32
+ const { sortToggle: sortToggleTitle, sortOrder: sortOrderTitle } =
33
+ useListSort(topics, topic => topic.title);
34
+
35
+ const { sortToggle: sortToggleDate, sortOrder: sortOrderDate } =
36
+ useListSort(topics, topic => topic.creation_date);
37
+
38
+ const sortedBy = ref("");
39
+
40
+ const sortByIndex = () => {
41
+ sortedBy.value = "index";
42
+ sortToggleIndex();
43
+ };
44
+ const sortByTitle = () => {
45
+ sortedBy.value = "title";
46
+ sortToggleTitle();
47
+ };
48
+ const sortByDate = () => {
49
+ sortedBy.value = "date";
50
+ sortToggleDate();
51
+ };
52
+
53
+ return {
54
+ sortedBy,
55
+ sortByIndex,
56
+ sortByTitle,
57
+ sortByDate,
58
+ sortOrderIndex,
59
+ sortOrderTitle,
60
+ sortOrderDate,
61
+ };
62
+ }
63
+
64
+ export { useBcfSort };