Skip to content

Commit

Permalink
Merge pull request #17487 from guerler/grid_tabs
Browse files Browse the repository at this point in the history
Consolidate resource grids into tab views
  • Loading branch information
mvdbeek authored Feb 23, 2024
2 parents 685912f + 5c4c778 commit 4e3ed4c
Show file tree
Hide file tree
Showing 36 changed files with 791 additions and 1,206 deletions.
48 changes: 41 additions & 7 deletions client/src/api/schema/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,13 @@ export interface paths {
*/
put: operations["set_slug_api_pages__id__slug_put"];
};
"/api/pages/{id}/undelete": {
/**
* Undelete the specific Page.
* @description Marks the Page with the given ID as undeleted.
*/
put: operations["undelete_api_pages__id__undelete_put"];
};
"/api/pages/{id}/unpublish": {
/**
* Removes this item from the published list.
Expand Down Expand Up @@ -18640,8 +18647,6 @@ export interface operations {
*/
parameters?: {
/** @description Whether to include deleted pages in the result. */
/** @description Sort page index by this specified attribute on the page model */
/** @description Sort in descending order? */
/**
* @description A mix of free text and GitHub-style tags used to filter the index operation.
*
Expand Down Expand Up @@ -18678,16 +18683,19 @@ export interface operations {
* Free text search terms will be searched against the following attributes of the
* Pages: `title`, `slug`, `tag`, `user`.
*/
/** @description Sort page index by this specified attribute on the page model */
/** @description Sort in descending order? */
query?: {
deleted?: boolean;
user_id?: string | null;
show_published?: boolean;
show_shared?: boolean;
sort_by?: "update_time" | "title" | "username";
sort_desc?: boolean;
limit?: number;
offset?: number;
search?: string | null;
show_own?: boolean;
show_published?: boolean;
show_shared?: boolean;
sort_by?: "create_time" | "title" | "update_time" | "username";
sort_desc?: boolean;
user_id?: string | null;
};
/** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */
header?: {
Expand Down Expand Up @@ -19050,6 +19058,32 @@ export interface operations {
};
};
};
undelete_api_pages__id__undelete_put: {
/**
* Undelete the specific Page.
* @description Marks the Page with the given ID as undeleted.
*/
parameters: {
/** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */
header?: {
"run-as"?: string | null;
};
/** @description The ID of the Page. */
path: {
id: string;
};
};
responses: {
/** @description Successful Response */
204: never;
/** @description Validation Error */
422: {
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
unpublish_api_pages__id__unpublish_put: {
/**
* Removes this item from the published list.
Expand Down
71 changes: 71 additions & 0 deletions client/src/components/Grid/GridHistory.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<script setup lang="ts">
import { library } from "@fortawesome/fontawesome-svg-core";
import { faPlus } from "@fortawesome/free-solid-svg-icons";
import { BNav, BNavItem } from "bootstrap-vue";
import historiesGridConfig from "@/components/Grid/configs/histories";
import historiesPublishedGridConfig from "@/components/Grid/configs/historiesPublished";
import historiesSharedGridConfig from "@/components/Grid/configs/historiesShared";
import { useUserStore } from "@/stores/userStore";
import Heading from "@/components/Common/Heading.vue";
import LoginRequired from "@/components/Common/LoginRequired.vue";
import GridList from "@/components/Grid/GridList.vue";
const userStore = useUserStore();
library.add(faPlus);
interface Props {
activeList?: "my" | "shared" | "published";
}
withDefaults(defineProps<Props>(), {
activeList: "my",
});
</script>

<template>
<div class="d-flex flex-column">
<div class="d-flex">
<Heading h1 separator inline size="xl" class="flex-grow-1 mb-2">Histories</Heading>
<div v-if="!userStore.isAnonymous">
<BButton
size="sm"
variant="outline-primary"
to="/histories/import"
data-description="grid action import new history">
<Icon :icon="faPlus" />
<span v-localize>Import History</span>
</BButton>
</div>
</div>
<BNav pills justified class="mb-2">
<BNavItem
id="histories-my-tab"
:active="activeList === 'my'"
:disabled="userStore.isAnonymous"
to="/histories/list">
My Histories
<LoginRequired v-if="userStore.isAnonymous" target="histories-my-tab" title="Manage your Histories" />
</BNavItem>
<BNavItem
id="histories-shared-tab"
:active="activeList === 'shared'"
:disabled="userStore.isAnonymous"
to="/histories/list_shared">
Shared with Me
<LoginRequired
v-if="userStore.isAnonymous"
target="histories-shared-tab"
title="Manage your Histories" />
</BNavItem>
<BNavItem id="histories-published-tab" :active="activeList === 'published'" to="/histories/list_published">
Public Histories
</BNavItem>
</BNav>
<GridList v-if="activeList === 'my'" :grid-config="historiesGridConfig" embedded />
<GridList v-else-if="activeList === 'shared'" :grid-config="historiesSharedGridConfig" embedded />
<GridList v-else :grid-config="historiesPublishedGridConfig" embedded />
</div>
</template>
9 changes: 6 additions & 3 deletions client/src/components/Grid/GridList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@ interface Props {
gridMessage?: string;
// debounce delay
delay?: number;
// embedded
embedded?: boolean;
// rows per page to be shown
limit?: number;
}
const props = withDefaults(defineProps<Props>(), {
delay: 5000,
embedded: false,
limit: 25,
});
Expand Down Expand Up @@ -237,7 +240,7 @@ watch(operationMessage, () => {
<BAlert v-if="!!errorMessage" variant="danger" show>{{ errorMessage }}</BAlert>
<BAlert v-if="!!operationMessage" :variant="operationStatus" fade show>{{ operationMessage }}</BAlert>
<div class="grid-header d-flex justify-content-between pb-2 flex-column">
<div class="d-flex">
<div v-if="!embedded" class="d-flex">
<Heading h1 separator inline size="xl" class="flex-grow-1 m-0" data-description="grid title">
<span v-localize>{{ gridConfig.title }}</span>
</Heading>
Expand All @@ -247,7 +250,7 @@ watch(operationMessage, () => {
:key="actionIndex"
class="m-1"
size="sm"
variant="primary"
variant="outline-primary"
:data-description="`grid action ${action.title.toLowerCase()}`"
@click="action.handler()">
<Icon :icon="action.icon" class="mr-1" />
Expand All @@ -256,7 +259,7 @@ watch(operationMessage, () => {
</div>
</div>
<FilterMenu
class="py-2"
:class="{ 'py-2': !embedded }"
:name="gridConfig.plural"
:placeholder="`search ${gridConfig.plural.toLowerCase()}`"
:filter-class="gridConfig.filtering"
Expand Down
52 changes: 52 additions & 0 deletions client/src/components/Grid/GridPage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<script setup lang="ts">
import { library } from "@fortawesome/fontawesome-svg-core";
import { faPlus } from "@fortawesome/free-solid-svg-icons";
import { BNav, BNavItem } from "bootstrap-vue";
import pagesGridConfig from "@/components/Grid/configs/pages";
import pagesPublishedGridConfig from "@/components/Grid/configs/pagesPublished";
import { useUserStore } from "@/stores/userStore";
import Heading from "@/components/Common/Heading.vue";
import LoginRequired from "@/components/Common/LoginRequired.vue";
import GridList from "@/components/Grid/GridList.vue";
const userStore = useUserStore();
library.add(faPlus);
interface Props {
activeList?: "my" | "published";
}
withDefaults(defineProps<Props>(), {
activeList: "my",
});
</script>

<template>
<div class="d-flex flex-column">
<div class="d-flex">
<Heading h1 separator inline size="xl" class="flex-grow-1 mb-2">Pages</Heading>
<div v-if="!userStore.isAnonymous">
<BButton id="page-create" size="sm" variant="outline-primary" to="/pages/create">
<Icon :icon="faPlus" />
<span v-localize>Create Page</span>
</BButton>
</div>
</div>
<BNav pills justified class="mb-2">
<BNavItem
id="pages-my-tab"
:active="activeList === 'my'"
:disabled="userStore.isAnonymous"
to="/pages/list">
My Pages
<LoginRequired v-if="userStore.isAnonymous" target="pages-my-tab" title="Manage your Pages" />
</BNavItem>
<BNavItem :active="activeList === 'published'" to="/pages/list_published"> Public Pages </BNavItem>
</BNav>
<GridList v-if="activeList === 'my'" :grid-config="pagesGridConfig" embedded />
<GridList v-else :grid-config="pagesPublishedGridConfig" embedded />
</div>
</template>
57 changes: 57 additions & 0 deletions client/src/components/Grid/GridVisualization.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<script setup lang="ts">
import { library } from "@fortawesome/fontawesome-svg-core";
import { faPlus } from "@fortawesome/free-solid-svg-icons";
import { BNav, BNavItem } from "bootstrap-vue";
import visualizationsGridConfig from "@/components/Grid/configs/visualizations";
import visualizationsPublishedGridConfig from "@/components/Grid/configs/visualizationsPublished";
import { useUserStore } from "@/stores/userStore";
import Heading from "@/components/Common/Heading.vue";
import LoginRequired from "@/components/Common/LoginRequired.vue";
import GridList from "@/components/Grid/GridList.vue";
const userStore = useUserStore();
library.add(faPlus);
interface Props {
activeList?: "my" | "published";
}
withDefaults(defineProps<Props>(), {
activeList: "my",
});
</script>

<template>
<div class="d-flex flex-column">
<div class="d-flex">
<Heading h1 separator inline size="xl" class="flex-grow-1 mb-2">Visualizations</Heading>
<div v-if="!userStore.isAnonymous">
<BButton size="sm" variant="outline-primary" to="/visualizations">
<Icon :icon="faPlus" />
<span v-localize>Create Visualization</span>
</BButton>
</div>
</div>
<BNav pills justified class="mb-2">
<BNavItem
id="visualizations-my-tab"
:active="activeList === 'my'"
:disabled="userStore.isAnonymous"
to="/visualizations/list">
My Visualizations
<LoginRequired
v-if="userStore.isAnonymous"
target="visualizations-my-tab"
title="Manage your Visualizations" />
</BNavItem>
<BNavItem :active="activeList === 'published'" to="/visualizations/list_published">
Public Visualizations
</BNavItem>
</BNav>
<GridList v-if="activeList === 'my'" :grid-config="visualizationsGridConfig" embedded />
<GridList v-else :grid-config="visualizationsPublishedGridConfig" embedded />
</div>
</template>
1 change: 1 addition & 0 deletions client/src/components/Grid/configs/histories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ async function getData(offset: number, limit: number, search: string, sort_by: s
sort_desc,
show_own: true,
show_published: false,
show_shared: false,
});
const totalMatches = parseInt(headers.get("total_matches") ?? "0");
return [data, totalMatches];
Expand Down
3 changes: 1 addition & 2 deletions client/src/components/Grid/configs/historiesPublished.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,8 @@ const fields: FieldArray = [
{
title: "View",
icon: faEye,
condition: (data: HistoryEntry) => !data.deleted,
handler: (data: HistoryEntry) => {
emit(`/histories/view?id=${data.id}`);
emit(`/published/history?id=${data.id}`);
},
},
],
Expand Down
Loading

0 comments on commit 4e3ed4c

Please sign in to comment.