1// Copyright (C) 2021 Storj Labs, Inc.
2// See LICENSE for copying information.
3
4import { ActionContext, ActionTree, GetterTree, Module, MutationTree } from 'vuex';
5
6import { RootState } from '@/app/store/index';
7import { Operator, Operators } from '@/operators';
8import { Cursor, Page } from '@/private/pagination';
9
10/**
11 * OperatorsState is a representation of operators module state.
12 */
13export class OperatorsState {
14    public constructor(
15        public operators: Operator[] = [],
16        public limit: number = 2,
17        public currentPage: number = 1,
18        public pageCount: number = 0,
19        public totalCount: number = 0,
20    ) {}
21}
22
23/**
24 * OperatorsModule is a part of a global store that encapsulates all operators related logic.
25 */
26export class OperatorsModule implements Module<OperatorsState, RootState> {
27    public readonly namespaced: boolean;
28    public readonly state: OperatorsState;
29    public readonly getters?: GetterTree<OperatorsState, RootState>;
30    public readonly actions: ActionTree<OperatorsState, RootState>;
31    public readonly mutations: MutationTree<OperatorsState>;
32
33    private readonly operators: Operators;
34
35    public constructor(operators: Operators) {
36        this.operators = operators;
37
38        this.namespaced = true;
39        this.state = new OperatorsState();
40
41        this.mutations = {
42            populate: this.populate,
43            updateCurrentPage: this.updateCurrentPage,
44        };
45
46        this.actions = {
47            listPaginated: this.listPaginated.bind(this),
48        };
49    }
50
51    /**
52     * populate mutation will set state with new operators array.
53     * @param state - state of the operators module.
54     * @param page - holds page which is used to show operators listed page.
55     */
56    public populate(state: OperatorsState, page: Page<Operator>): void {
57        state.operators = page.items;
58        state.limit = page.limit;
59        state.currentPage = page.currentPage;
60        state.pageCount = page.pageCount;
61        state.totalCount = page.totalCount;
62    }
63
64    /**
65     * updates current page.
66     * @param state - state of the operators module.
67     * @param pageNumber - desired page number.
68     */
69    public updateCurrentPage(state: OperatorsState, pageNumber: number): void {
70        state.currentPage = pageNumber;
71    }
72
73    /**
74     * listPaginated action loads page with operators.
75     * @param ctx - context of the Vuex action.
76     * @param pageNumber - number of page to get.
77     */
78    public async listPaginated(ctx: ActionContext<OperatorsState, RootState>, pageNumber: number): Promise<void> {
79        const cursor: Cursor = new Cursor(ctx.state.limit, pageNumber);
80        const page = await this.operators.listPaginated(cursor);
81
82        ctx.commit('updateCurrentPage', pageNumber);
83        ctx.commit('populate', page);
84    }
85}
86