Skip to content

Instantly share code, notes, and snippets.

@zohaibhassan156
Created March 28, 2025 14:27
Show Gist options
  • Save zohaibhassan156/6e19580f0c83df888458baa095148942 to your computer and use it in GitHub Desktop.
Save zohaibhassan156/6e19580f0c83df888458baa095148942 to your computer and use it in GitHub Desktop.
list-page mixin Vue
import Vue from 'vue';
import { DataOptions } from 'vuetify';
import { Watch } from 'vue-property-decorator';
import Component from 'vue-class-component';
import Toast from '@/utils/toast';
import sleep from '@/utils/sleep';
const initPageSize = 10;
@Component
export default class ListPage<Model> extends Vue {
namespace!: string;
loading = false;
firstLoadFinished = false;
initPageSize = initPageSize;
noDataText = '';
tableOptions: DataOptions = {
page: 1,
itemsPerPage: this.initPageSize,
sortBy: [],
sortDesc: [],
groupBy: [],
groupDesc: [],
multiSort: false,
mustSort: false,
};
defaultFilterValue: FormValues = {};
originalStaticSearchOptions = {};
get staticSearchOptions(): URLParameters {
return this.originalStaticSearchOptions;
}
get namespaceState(): PaginationState<Model> {
const namespaceList = this.namespace.split('/');
return namespaceList.reduce(
(state, namespace) => state[namespace],
this.$store.state,
) as PaginationState<Model>;
}
get items(): Model[] {
return this.namespaceState.items;
}
get pagination(): Pagination {
return this.namespaceState.pagination;
}
@Watch('tableOptions')
async onTableOptionsChange(val: DataOptions) {
if (this.firstLoadFinished) {
try {
this.loading = true;
const {
page,
itemsPerPage
} = val;
await sleep();
await this.$store.dispatch(`${this.namespace}/getList`, {
page,
size: itemsPerPage
});
this.noDataText = this.$t('common.no_data_available') as string;
} catch (e) {
console.error(e);
this.noDataText = this.$t('common.load_failure') as string;
} finally {
this.loading = false;
}
}
}
silentResetTableOptions() {
this.tableOptions.page = 1;
this.tableOptions.itemsPerPage = initPageSize;
this.tableOptions.sortBy = [];
this.tableOptions.sortDesc = [];
this.tableOptions.groupBy = [];
this.tableOptions.groupDesc = [];
this.tableOptions.mustSort = false;
this.tableOptions.multiSort = false;
}
async refreshCurrentPage(options?: {
page?: number
}): Promise<void> {
try {
this.loading = true;
if (typeof options?.page === 'number') {
this.tableOptions.page = options.page;
}
const {
page,
size
} = this.pagination;
await this.$store.dispatch(`${this.namespace}/getList`, {
page,
size
});
this.noDataText = this.$t('common.no_data_available') as string;
} catch (e) {
console.error(e);
this.noDataText = this.$t('common.load_failure') as string;
} finally {
this.loading = false;
}
}
async onSearch(options: URLParameters): Promise<void> {
try {
this.loading = true;
await this.$store.dispatch(`${this.namespace}/setSearchOptions`, {
...this.staticSearchOptions,
...options,
});
const {
page,
size
} = this.pagination;
if (page === 1) {
await this.$store.dispatch(`${this.namespace}/getList`, {
page,
size
});
} else {
this.tableOptions.page = 1;
this.tableOptions.itemsPerPage = size;
}
this.noDataText = this.$t('common.no_data_available') as string;
} catch (e) {
console.error(e);
this.noDataText = this.$t('common.load_failure') as string;
} finally {
this.loading = false;
}
}
async onDelete(id: number, syncCostToWc: boolean): Promise<void> {
await this.$store.dispatch(`${this.namespace}/delete`, {
id,
syncCostToWc
});
Toast.success(this.$t('errors.success') as string);
}
async firstLoad(fetchOptions = false,
searchOptions?: Record<string | number | symbol, unknown>,
options?: {
beforeGetList?: () => Promise<void> | void
}): Promise<void> {
try {
this.loading = true;
await this.$store.dispatch(`${this.namespace}/resetState`);
if (fetchOptions) {
await this.$store.dispatch(`${this.namespace}/fetchOptions`);
}
if (options?.beforeGetList) {
await options.beforeGetList();
}
await this.$store.dispatch(
`${this.namespace}/getList`,
{
page: 1,
size: this.initPageSize,
searchOptions: {
...this.staticSearchOptions,
...this.defaultFilterValue,
...searchOptions || {}
},
},
);
this.noDataText = this.$t('common.no_data_available') as string;
} catch (e) {
console.error(e);
this.noDataText = this.$t('common.load_failure') as string;
} finally {
this.loading = false;
this.firstLoadFinished = true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment