Skip to content

Commit

Permalink
feat: add auto pagination (#18)
Browse files Browse the repository at this point in the history
* feat: add auto pagination

* style: rename components.

* chore(ui): css style update.

* chore: loading card unit is increased from 5 to 25 per page.

* docs: update README.md.
  • Loading branch information
shocota authored Jan 19, 2023
1 parent d50a666 commit b882961
Show file tree
Hide file tree
Showing 6 changed files with 426 additions and 222 deletions.
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ Place `index.js` in the `${DIRECTUS_PROJECT_ROOT_FOLDER}/extensions/layout/board
## Usage
- You must set a field interface to *dropdown* to choose as a Group By option.

## Current limitation
- No paging feature! I highly prioritize to add it.
- Many group derives too heavy API & SQL request.

# License

This repository is licensed under the GPLv3 License. See the LICENSE file for details.
Expand Down
28 changes: 16 additions & 12 deletions src/board.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="boards-layout">
<lane-component
<paginate-group
v-for="choice in choices"
:key="choice.text"
:field="field"
Expand All @@ -14,15 +14,20 @@
</template>

<script lang="ts">
import {
useCollection,
} from "@directus/extensions-sdk";
import { useCollection } from "@directus/extensions-sdk";
import { Field, Filter } from "@directus/shared/types";
import { computed, defineComponent, PropType, toRefs } from "vue";
import LaneComponent from "./components/lane.vue";
import {
computed,
defineComponent,
onMounted,
PropType,
ref,
toRefs,
} from "vue";
import paginateGroup from "./components/paginateGroup.vue";
import { LayoutOptions } from "./types";
export default defineComponent({
components: { LaneComponent },
components: { paginateGroup },
inheritAttrs: false,
props: {
layoutOptions: { type: Object as PropType<LayoutOptions> },
Expand All @@ -40,14 +45,13 @@ export default defineComponent({
},
},
setup(props, { emit }) {
const {
collection: collectionKey,
layoutOptions,
} = toRefs(props);
const { collection: collectionKey, layoutOptions } = toRefs(props);
const collection = useCollection(collectionKey);
const field = computed<Field | undefined>(() =>
collection.fields.value.find((f) => f.field == layoutOptions.value?.groupByField)
collection.fields.value.find(
(f) => f.field == layoutOptions.value?.groupByField
)
);
const choices = computed<{ text: string }[]>(
() => field.value?.meta?.options?.choices || []
Expand Down
206 changes: 0 additions & 206 deletions src/components/lane.vue

This file was deleted.

116 changes: 116 additions & 0 deletions src/components/paginateGroup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<template>
<section>
<header>
<component
:is="`display-${field?.meta?.display}`"
v-bind="field?.meta?.display_options"
:type="field?.type"
:value="fieldValue"
/>
</header>
<main class="paginate-units">
<paginate-unit
v-for="page in pages"
:key="page"
:page="page"
:collection-key="collectionKey"
:field="field"
:field-value="fieldValue"
:layout-options="layoutOptions"
:filter="filter"
:search="search"
@hasNextPage="hundleHasNextPage"
/>
</main>
</section>
</template>
<script lang="ts">
import { Field, Filter, LogicalFilterAND } from "@directus/shared/types";
import { computed, defineComponent, PropType, ref, toRefs, watch } from "vue";
import { LayoutOptions } from "../types";
import PaginateUnit from "./paginateUnit.vue";
export default defineComponent({
components: { PaginateUnit },
inheritAttrs: false,
props: {
collection: { type: String, required: true },
field: { type: Object as PropType<Field> },
fieldValue: { type: String },
layoutOptions: { type: Object as PropType<LayoutOptions> },
filter: {
type: Object as PropType<Filter | null>,
default: null,
},
search: {
type: String as PropType<string | null>,
default: null,
},
},
setup(props) {
const {
fieldValue,
field,
filter: originFilter,
collection: collectionKey,
search,
layoutOptions,
} = toRefs(props);
const pages = ref([1])
const filter = computed<LogicalFilterAND>(() => ({
_and: [
{ [field.value!.field]: { _eq: fieldValue.value } },
originFilter.value || {},
],
}));
const sort = computed(() => layoutOptions.value?.sort);
watch([filter, sort, search], (after, before) => {
if (JSON.stringify(after) != JSON.stringify(before)) {
pages.value = [1];
}
});
function hundleHasNextPage(page: number) {
pages.value = [...new Set([...pages.value, page])];
}
return { pages, collectionKey, hundleHasNextPage };
},
});
</script>
<style scoped>
section {
background-color: var(--background-subdued);
border-radius: var(--border-radius);
flex: 0 0 320px;
display: flex;
flex-flow: column nowrap;
align-items: stretch;
}
header {
padding: 16px 16px 0 16px;
display: flex;
justify-content: space-between;
}
.paginate-units {
padding: 16px;
flex-grow: 1;
display: flex;
flex-flow: column nowrap;
}
.paginate-units > * {
flex: 0 0 auto;
}
.paginate-units > *:last-child {
flex-grow: 1;
}
</style>
Loading

0 comments on commit b882961

Please sign in to comment.