chore: Save company list sorting preferences in UI settings (#12916)
# Pull Request Template ## Description This PR saves the company list sorting preferences (field and order) in the user’s UI settings. The sort state is initialized from the stored preferences when the component mounts, defaulting to `-created_at` if none exist. Fixes https://linear.app/chatwoot/issue/CW-5992/save-sort-filter-to-ui-settings ## Type of change - [x] New feature (non-breaking change which adds functionality) ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules
This commit is contained in:
@@ -1,14 +1,16 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from 'vue';
|
import { ref, computed, onMounted, reactive } from 'vue';
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useMapGetter } from 'dashboard/composables/store';
|
import { useMapGetter } from 'dashboard/composables/store';
|
||||||
|
import { useUISettings } from 'dashboard/composables/useUISettings';
|
||||||
import { debounce } from '@chatwoot/utils';
|
import { debounce } from '@chatwoot/utils';
|
||||||
|
|
||||||
import CompaniesListLayout from 'dashboard/components-next/Companies/CompaniesListLayout.vue';
|
import CompaniesListLayout from 'dashboard/components-next/Companies/CompaniesListLayout.vue';
|
||||||
import CompaniesCard from 'dashboard/components-next/Companies/CompaniesCard/CompaniesCard.vue';
|
import CompaniesCard from 'dashboard/components-next/Companies/CompaniesCard/CompaniesCard.vue';
|
||||||
|
|
||||||
|
const DEFAULT_SORT_FIELD = 'created_at';
|
||||||
const DEBOUNCE_DELAY = 300;
|
const DEBOUNCE_DELAY = 300;
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
@@ -16,19 +18,33 @@ const route = useRoute();
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const { updateUISettings, uiSettings } = useUISettings();
|
||||||
|
|
||||||
const searchQuery = computed(() => route.query?.search || '');
|
const searchQuery = computed(() => route.query?.search || '');
|
||||||
const searchValue = ref(searchQuery.value);
|
const searchValue = ref(searchQuery.value);
|
||||||
const pageNumber = computed(() => Number(route.query?.page) || 1);
|
const pageNumber = computed(() => Number(route.query?.page) || 1);
|
||||||
|
|
||||||
const activeSort = computed(() => {
|
const parseSortSettings = (sortString = '') => {
|
||||||
const sortParam = route.query?.sort || 'name';
|
const hasDescending = sortString.startsWith('-');
|
||||||
return sortParam.startsWith('-') ? sortParam.slice(1) : sortParam;
|
const sortField = hasDescending ? sortString.slice(1) : sortString;
|
||||||
|
return {
|
||||||
|
sort: sortField || DEFAULT_SORT_FIELD,
|
||||||
|
order: hasDescending ? '-' : '',
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const { companies_sort_by: companySortBy = `-${DEFAULT_SORT_FIELD}` } =
|
||||||
|
uiSettings.value ?? {};
|
||||||
|
const { sort: initialSort, order: initialOrder } =
|
||||||
|
parseSortSettings(companySortBy);
|
||||||
|
|
||||||
|
const sortState = reactive({
|
||||||
|
activeSort: initialSort,
|
||||||
|
activeOrdering: initialOrder,
|
||||||
});
|
});
|
||||||
|
|
||||||
const activeOrdering = computed(() => {
|
const activeSort = computed(() => sortState.activeSort);
|
||||||
const sortParam = route.query?.sort || 'name';
|
const activeOrdering = computed(() => sortState.activeOrdering);
|
||||||
return sortParam.startsWith('-') ? '-' : '';
|
|
||||||
});
|
|
||||||
|
|
||||||
const companies = useMapGetter('companies/getCompaniesList');
|
const companies = useMapGetter('companies/getCompaniesList');
|
||||||
const meta = useMapGetter('companies/getMeta');
|
const meta = useMapGetter('companies/getMeta');
|
||||||
@@ -36,11 +52,10 @@ const uiFlags = useMapGetter('companies/getUIFlags');
|
|||||||
|
|
||||||
const isFetchingList = computed(() => uiFlags.value.fetchingList);
|
const isFetchingList = computed(() => uiFlags.value.fetchingList);
|
||||||
|
|
||||||
const sortParam = computed(() => {
|
const buildSortAttr = () =>
|
||||||
return activeOrdering.value === '-'
|
`${sortState.activeOrdering}${sortState.activeSort}`;
|
||||||
? `-${activeSort.value}`
|
|
||||||
: activeSort.value;
|
const sortParam = computed(() => buildSortAttr());
|
||||||
});
|
|
||||||
|
|
||||||
const updateURLParams = (page, search = '', sort = '') => {
|
const updateURLParams = (page, search = '', sort = '') => {
|
||||||
const query = {
|
const query = {
|
||||||
@@ -96,9 +111,14 @@ const onPageChange = page => {
|
|||||||
fetchCompanies(page, searchValue.value, sortParam.value);
|
fetchCompanies(page, searchValue.value, sortParam.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSort = ({ sort, order }) => {
|
const handleSort = async ({ sort, order }) => {
|
||||||
const newSortParam = order === '-' ? `-${sort}` : sort;
|
Object.assign(sortState, { activeSort: sort, activeOrdering: order });
|
||||||
fetchCompanies(1, searchValue.value, newSortParam);
|
|
||||||
|
await updateUISettings({
|
||||||
|
companies_sort_by: buildSortAttr(),
|
||||||
|
});
|
||||||
|
|
||||||
|
fetchCompanies(1, searchValue.value, buildSortAttr());
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user