pocketbase/ui/src/components/records/PageRecords.svelte

208 lines
7.1 KiB
Svelte
Raw Normal View History

2022-07-07 05:19:05 +08:00
<script>
2022-08-01 19:20:21 +08:00
import { replace, querystring } from "svelte-spa-router";
2023-02-19 01:33:42 +08:00
import CommonHelper from "@/utils/CommonHelper";
2022-07-07 05:19:05 +08:00
import {
collections,
activeCollection,
isCollectionsLoading,
loadCollections,
2022-10-30 16:28:14 +08:00
changeActiveCollectionById,
2022-07-07 05:19:05 +08:00
} from "@/stores/collections";
import tooltip from "@/actions/tooltip";
2022-08-18 22:10:42 +08:00
import { pageTitle, hideControls } from "@/stores/app";
2022-08-09 21:16:09 +08:00
import PageWrapper from "@/components/base/PageWrapper.svelte";
2022-07-07 05:19:05 +08:00
import Searchbar from "@/components/base/Searchbar.svelte";
import RefreshButton from "@/components/base/RefreshButton.svelte";
2022-07-07 05:19:05 +08:00
import CollectionsSidebar from "@/components/collections/CollectionsSidebar.svelte";
import CollectionUpsertPanel from "@/components/collections/CollectionUpsertPanel.svelte";
2022-10-30 16:28:14 +08:00
import CollectionDocsPanel from "@/components/collections/CollectionDocsPanel.svelte";
2022-07-07 05:19:05 +08:00
import RecordUpsertPanel from "@/components/records/RecordUpsertPanel.svelte";
2023-02-19 01:33:42 +08:00
import RecordPreviewPanel from "@/components/records/RecordPreviewPanel.svelte";
2022-07-07 05:19:05 +08:00
import RecordsList from "@/components/records/RecordsList.svelte";
2022-08-01 19:20:21 +08:00
const queryParams = new URLSearchParams($querystring);
2022-07-07 05:19:05 +08:00
let collectionUpsertPanel;
let collectionDocsPanel;
2023-02-19 01:33:42 +08:00
let recordUpsertPanel;
let recordPreviewPanel;
2022-07-07 05:19:05 +08:00
let recordsList;
2022-08-01 19:20:21 +08:00
let filter = queryParams.get("filter") || "";
2023-06-09 18:07:34 +08:00
let sort = queryParams.get("sort") || "-created";
let selectedCollectionId = queryParams.get("collectionId") || $activeCollection?.id;
2022-07-07 05:19:05 +08:00
2022-10-30 16:28:14 +08:00
$: reactiveParams = new URLSearchParams($querystring);
$: if (
!$isCollectionsLoading &&
reactiveParams.get("collectionId") &&
2022-10-30 16:28:14 +08:00
reactiveParams.get("collectionId") != selectedCollectionId
) {
changeActiveCollectionById(reactiveParams.get("collectionId"));
}
2022-07-07 05:19:05 +08:00
// reset filter and sort on collection change
$: if ($activeCollection?.id && selectedCollectionId != $activeCollection.id) {
reset();
2022-07-07 05:19:05 +08:00
}
$: if ($activeCollection?.id) {
normalizeSort();
}
2022-07-07 05:19:05 +08:00
// keep the url params in sync
$: if (sort || filter || $activeCollection?.id) {
2022-08-01 19:20:21 +08:00
const query = new URLSearchParams({
collectionId: $activeCollection?.id || "",
2022-07-07 05:19:05 +08:00
filter: filter,
sort: sort,
2022-08-01 19:20:21 +08:00
}).toString();
replace("/collections?" + query);
2022-07-07 05:19:05 +08:00
}
$: $pageTitle = $activeCollection?.name || "Collections";
function reset() {
2023-02-19 01:33:42 +08:00
selectedCollectionId = $activeCollection?.id;
filter = "";
2023-02-19 01:33:42 +08:00
sort = "-created";
normalizeSort();
}
// ensures that the sort fields exist in the collection
async function normalizeSort() {
if (!sort) {
return; // nothing to normalize
}
const collectionFields = CommonHelper.getAllCollectionIdentifiers($activeCollection);
const sortFields = sort.split(",").map((f) => {
if (f.startsWith("+") || f.startsWith("-")) {
return f.substring(1);
}
return f;
});
// invalid sort expression or missing sort field
if (sortFields.filter((f) => collectionFields.includes(f)).length != sortFields.length) {
if (collectionFields.includes("created")) {
sort = "-created";
} else {
sort = "";
}
2023-02-19 01:33:42 +08:00
}
}
2022-07-07 05:19:05 +08:00
loadCollections(selectedCollectionId);
</script>
{#if $isCollectionsLoading && !$collections.length}
2022-08-09 21:16:09 +08:00
<PageWrapper center>
<div class="placeholder-section m-b-base">
<span class="loader loader-lg" />
<h1>Loading collections...</h1>
</div>
</PageWrapper>
2022-10-30 16:28:14 +08:00
{:else if !$collections.length}
2022-08-09 21:16:09 +08:00
<PageWrapper center>
<div class="placeholder-section m-b-base">
<div class="icon">
<i class="ri-database-2-line" />
</div>
2022-08-18 22:10:42 +08:00
{#if $hideControls}
<h1 class="m-b-10">You don't have any collections yet.</h1>
{:else}
<h1 class="m-b-10">Create your first collection to add records!</h1>
<button
type="button"
class="btn btn-expanded-lg btn-lg"
on:click={() => collectionUpsertPanel?.show()}
>
<i class="ri-add-line" />
<span class="txt">Create new collection</span>
</button>
{/if}
2022-07-07 05:19:05 +08:00
</div>
2022-08-09 21:16:09 +08:00
</PageWrapper>
2022-07-07 05:19:05 +08:00
{:else}
<CollectionsSidebar />
2022-08-09 21:16:09 +08:00
<PageWrapper>
2022-07-07 05:19:05 +08:00
<header class="page-header">
<nav class="breadcrumbs">
<div class="breadcrumb-item">Collections</div>
<div class="breadcrumb-item">{$activeCollection.name}</div>
</nav>
2022-08-05 11:00:38 +08:00
<div class="inline-flex gap-5">
2022-08-18 22:10:42 +08:00
{#if !$hideControls}
<button
type="button"
aria-label="Edit collection"
class="btn btn-transparent btn-circle"
2022-08-18 22:10:42 +08:00
use:tooltip={{ text: "Edit collection", position: "right" }}
on:click={() => collectionUpsertPanel?.show($activeCollection)}
>
<i class="ri-settings-4-line" />
</button>
{/if}
2022-08-05 11:00:38 +08:00
<RefreshButton on:refresh={() => recordsList?.load()} />
</div>
2022-07-07 05:19:05 +08:00
<div class="btns-group">
<button
type="button"
class="btn btn-outline"
on:click={() => collectionDocsPanel?.show($activeCollection)}
>
<i class="ri-code-s-slash-line" />
<span class="txt">API Preview</span>
</button>
2023-03-28 00:43:46 +08:00
{#if !$activeCollection.$isView}
2023-02-19 01:33:42 +08:00
<button type="button" class="btn btn-expanded" on:click={() => recordUpsertPanel?.show()}>
<i class="ri-add-line" />
<span class="txt">New record</span>
</button>
{/if}
2022-07-07 05:19:05 +08:00
</div>
</header>
<Searchbar
value={filter}
autocompleteCollection={$activeCollection}
on:submit={(e) => (filter = e.detail)}
/>
<div class="clearfix m-b-base" />
2022-07-07 05:19:05 +08:00
<RecordsList
bind:this={recordsList}
collection={$activeCollection}
bind:filter
bind:sort
2023-02-19 01:33:42 +08:00
on:select={(e) => {
2023-03-28 00:43:46 +08:00
$activeCollection.$isView
2023-02-19 01:33:42 +08:00
? recordPreviewPanel.show(e?.detail)
: recordUpsertPanel?.show(e?.detail);
}}
on:new={() => recordUpsertPanel?.show()}
2022-07-07 05:19:05 +08:00
/>
2022-08-09 21:16:09 +08:00
</PageWrapper>
2022-07-07 05:19:05 +08:00
{/if}
<CollectionUpsertPanel bind:this={collectionUpsertPanel} />
2022-07-07 05:19:05 +08:00
<CollectionDocsPanel bind:this={collectionDocsPanel} />
<RecordUpsertPanel
2023-02-19 01:33:42 +08:00
bind:this={recordUpsertPanel}
2022-07-07 05:19:05 +08:00
collection={$activeCollection}
on:save={() => recordsList?.reloadLoadedPages()}
on:delete={() => recordsList?.reloadLoadedPages()}
2022-07-07 05:19:05 +08:00
/>
2023-02-19 01:33:42 +08:00
<RecordPreviewPanel bind:this={recordPreviewPanel} collection={$activeCollection} />