Discovery - Creating a Vue Component for tables that handles server side/client side pagination.
- Zoom call recording: https://drive.google.com/drive/u/1/folders/1wzGuUOamqs8gtv8bZH25WyZsDMc-F4xV
Current usages of tables:
Current uses of gl-pagination: (to give an idea of where we have paginated data/tables):
/Users/fernando/gitlab/gdk-ee/gitlab/app/assets/javascripts/error_tracking/components/error_tracking_list.vue /Users/fernando/gitlab/gdk-ee/gitlab/app/assets/javascripts/issuables_list/components/issuables_list_app.vue /Users/fernando/gitlab/gdk-ee/gitlab/app/assets/javascripts/vue_shared/components/pagination_links.vue /Users/fernando/gitlab/gdk-ee/gitlab/app/assets/javascripts/vue_shared/components/pagination/table_pagination.vue /Users/fernando/gitlab/gdk-ee/gitlab/ee/app/assets/javascripts/analytics/code_review_analytics/components/app.vue /Users/fernando/gitlab/gdk-ee/gitlab/ee/app/assets/javascripts/geo_designs/components/geo_designs.vue /Users/fernando/gitlab/gdk-ee/gitlab/ee/app/assets/javascripts/packages/list/components/packages_list.vue
Current uses of table-pagination (pagination for the table, not actually a table): /Users/fernando/gitlab/gdk-ee/gitlab/app/assets/javascripts/commit/pipelines/pipelines_table.vue /Users/fernando/gitlab/gdk-ee/gitlab/app/assets/javascripts/environments/components/container.vue /Users/fernando/gitlab/gdk-ee/gitlab/app/assets/javascripts/pipelines/components/pipelines.vue /Users/fernando/gitlab/gdk-ee/gitlab/app/assets/javascripts/registry/list/components/table_registry.vue /Users/fernando/gitlab/gdk-ee/gitlab/app/assets/javascripts/releases/list/components/app.vue /Users/fernando/gitlab/gdk-ee/gitlab/ee/app/assets/javascripts/feature_flags/components/feature_flags.vue /Users/fernando/gitlab/gdk-ee/gitlab/ee/app/assets/javascripts/pages/groups/saml_providers/saml_members/index.vue
Client Side Pagination w/ PaginatedList component (from gitlab-ui): /Users/fernando/gitlab/gdk-ee/gitlab/ee/app/assets/javascripts/vue_shared/license_management/license_management.vue
Repeated boilerplate code in above usages
- Manually wiring up gl-pagination/table-pagination, to the table rows.
- Implementing server request. In some cases it lives in a vuex action, in legacy code it uses EventBus.
- We re-implement the table/row markup. (Markup can be different depending on when table was implemented, possibly inconsistent support for responsive layouts)
- Forced to re-implement unit tests, for common table behavior. (We shouldn't need to constantly re-test common table logic like row rendering, table sorting, etc)
- Sorting/Filtering
- Parsing of JSON response
Desired Functionality
- Ensure we support semantic table markup (
<table>,<tr>, <td>elements). Otherwise we cause usability issues with copy/pasting table data from the browser, into Spreadsheets, Word Processors. - Abstracting out the repetitive logic out into a re-usable component (internal state?, Vuex Modules, Dynamic Modules)
- Sorting
- Filtering
- Custom rows (slots?)
- Search (supporting client side and server side search).
- Custom loading content (slot)
- Custom empty state (slot)
- Custom header content (slot) (Ex. buttons)
- Sticky headers
- Responsive layouts (mobile, small width)
- Footer? (Question for UX?)
- Emitted events? (Which do we emit?)
- Also take into consideration the functionality desired in gitlab-ui#561 (comment 273816932)
Questions to Answer
-
Where does this component live? (Gitlab UI vs. Gitlab codebase)
-
Do we build the server table/pagination logic on top of the gl-paginatied-list component in gitlab-ui. If we do, we'd need to add additional functionality to the gl-paginated-list component.
-
Where do translations live? Currently we wrap gitlab-ui components in vue_shared (which is suppose to be deprecated, I think), to add in I18n translations by passing in the text as props.
-
If we use a vuex module, what happens when we want to use the table in legacy code where we don't have a vuex store? Can we use a vue plugin (https://vuejs.org/v2/guide/plugins.html) to conditionally instantiate a vuex store when it doesn't exist.
-
For existing vuex apps, do we expect the user to know to register the table vuex module. (we can handle this with docs).... question for maintainers..... this would be a perfect use case for dynamic module registration. Hook into vue lifecycle event (beforeCreate, created?)
-
How do we handle multiple table instances? (Dynamic module registration w/ namespace passed in as a prop for the table)
Todo:
-
Work through existing usages of tables in Gitlab codebase to determine existing use cases. (What are the most common usages we should support). This would help define an interface for the component (props, emittedEvents).
-
Re-work gl-paginated-list to use proper table markup (
<table>, <td>, <tr>)