Skip to content

Commit

Permalink
Merge pull request #470 from MuckRock/document-count
Browse files Browse the repository at this point in the history
Adds document count to ActionBar
  • Loading branch information
allanlasser authored Mar 19, 2024
2 parents 1841897 + 999b84a commit 52c866b
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 126 deletions.
2 changes: 1 addition & 1 deletion src/langs/json/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@
"paginator": {
"page": "Page",
"of": "of",
"document": "{n, plural, one {Document} other {Documents}}",
"document": "{n, plural, one {# Document} other {# Documents}}",
"next": "Next Page",
"previous": "Previous Page",
"first": "First Page",
Expand Down
254 changes: 130 additions & 124 deletions src/pages/app/ActionBar.svelte
Original file line number Diff line number Diff line change
@@ -1,157 +1,163 @@
<script>
import Checkbox from "@/common/Checkbox.svelte";
import Tooltip from "@/common/Tooltip.svelte";
import Dropdown from "@/common/Dropdown.svelte";
import Paginator from "../../common/Paginator.svelte";
<script lang="ts">
import { _ } from "svelte-i18n";
import Checkbox from "../../common/Checkbox.svelte";
import Flex from "../../common/Flex.svelte";
import Tooltip from "../../common/Tooltip.svelte";
import Dropdown from "../../common/Dropdown.svelte";
import Paginator from "../../common/Paginator.svelte";
// Menus
import EditMenu from "./menus/EditMenu.svelte";
import ProjectsMenu from "./menus/ProjectsMenu.svelte";
import AddonsMenu from "./menus/AddonsMenu.svelte";
// Stores
import { search, searchNext, searchPrev } from "@/search/search.js";
import { layout } from "@/manager/layout.js";
import { manager, selectAll } from "@/manager/manager.js";
import { documents, unselectAll } from "@/manager/documents.js";
import { orgsAndUsers } from "@/manager/orgsAndUsers.js";
let outerHeight = 1000;
let editVisible = false;
export let loggedIn: boolean;
export let data: {
loading: boolean;
documents: Array<any>;
};
export let selection: {
checked: boolean;
indeterminate: boolean;
editable: boolean;
onUncheck: () => void;
onCheck: () => void;
};
export let pagination: {
page: number;
totalPages?: number;
totalItems?: number;
onNext: () => void;
onPrev: () => void;
has_next: boolean;
has_prev: boolean;
};
function handleSelectAll({ detail }) {
if (!detail.indeterminate) selectAll();
if (!detail.indeterminate) selection.onCheck();
}
let outerHeight = 1000;
let editVisible = false;
</script>

<div class="barcontainer">
{#if !$layout.loading}
<div class="bar">
{#if $orgsAndUsers.loggedIn}
<span class="action check scaledown">
{#if $documents.documents.length > 0}
<Checkbox
on:check={handleSelectAll}
on:uncheck={unselectAll}
indeterminate={$manager.someSelected}
checked={$layout.hasSelection}
/>
{/if}
</span>
{#if !data.loading}
<Flex gap={2} align="center" justify="space-between">
<Flex gap={2} align="center">
{#if loggedIn}
<span class="action check scaledown">
{#if data.documents.length > 0}
<Checkbox
on:check={handleSelectAll}
on:uncheck={selection.onUncheck}
indeterminate={selection.indeterminate}
checked={selection.checked}
/>
{/if}
</span>

{#if $layout.hasSelection && $layout.selectionEditable}
<Dropdown
name="edit-menu"
table={true}
fixed={outerHeight > 600}
on:active={(e) => (editVisible = e.detail)}
>
{#if selection.checked && selection.editable}
<Dropdown
name="edit-menu"
table={true}
fixed={outerHeight > 600}
on:active={(e) => (editVisible = e.detail)}
>
<span class="action nowrap" slot="title">
{$_("actionBar.editMenu")}
<span class="dropper">▼</span>
</span>
<EditMenu visible={editVisible} />
</Dropdown>
{:else}
<span class="action disabled shortpad nowrap">
<Tooltip
caption={selection.editable
? $_("actionBar.selectDocs")
: $_("actionBar.noPerms")}
>
{$_("actionBar.editMenu")}
<span class="dropper">▼</span>
</Tooltip>
</span>
{/if}
<Dropdown name="projects-menu" table={true} fixed={outerHeight > 600}>
<span class="action nowrap" slot="title">
{$_("actionBar.editMenu")}
{$_("actionBar.projectsMenu")}
<span class="dropper">▼</span>
</span>
<EditMenu visible={editVisible} />
<ProjectsMenu />
</Dropdown>
<Dropdown name="addons-menu" table={true} fixed={outerHeight > 600}>
<span class="action nowrap" slot="title">
<span>
{$_("actionBar.addOnsMenu")}
<span class="dropper">▼</span>
</span>
</span>
<AddonsMenu />
</Dropdown>
{:else}
<span class="action disabled shortpad nowrap">
<Tooltip
caption={$layout.selectionEditable
? $_("actionBar.selectDocs")
: $_("actionBar.noPerms")}
>
{$_("actionBar.editMenu")}
<span class="dropper">▼</span>
</Tooltip>
</span>
{/if}
<Dropdown name="projects-menu" table={true} fixed={outerHeight > 600}>
<span class="action nowrap" slot="title">
{$_("actionBar.projectsMenu")}
<span class="dropper">▼</span>
</span>
<ProjectsMenu />
</Dropdown>
<Dropdown name="addons-menu" table={true} fixed={outerHeight > 600}>
<span class="action nowrap" slot="title">
<span class="badge"> {$_("common.new")}! </span>
{$_("actionBar.addOnsMenu")}
<span class="dropper">▼</span>
</span>
<AddonsMenu />
</Dropdown>
{/if}

<span class="narrowhide">
<Paginator
page={$search.page}
totalPages={$search.results?.numPages}
on:next={searchNext}
on:previous={searchPrev}
has_next={$search.hasNext}
has_previous={$search.hasPrev}
/>
</span>
</div>
</Flex>
<Flex gap={2} align="center">
{#if pagination.totalItems}
<div class="documents">
{$_("paginator.document", { values: { n: pagination.totalItems } })}
</div>
{/if}
<span class="narrowhide">
<Paginator
page={pagination.page}
totalPages={pagination.totalPages}
on:next={pagination.onNext}
on:previous={pagination.onPrev}
has_next={pagination.has_next}
has_previous={pagination.has_prev}
/>
</span>
</Flex>
</Flex>
{/if}
</div>

<svelte:window bind:outerHeight />

<style lang="scss">
<style>
.barcontainer {
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
padding: 14px 0;
padding: 0.75rem 0;
color: var(--darkgray);
}
.nowrap {
white-space: nowrap;
}
.nowrap {
white-space: nowrap;
}
.bar {
display: table-row;
.action {
font-size: 16px;
color: $primary;
padding: 0 25px;
user-select: none;
cursor: pointer;
display: table-cell;
vertical-align: middle;
&.check {
padding-right: 35px;
cursor: inherit;
transform: translateY(2px);
}
&.disabled {
color: $gray;
cursor: inherit;
}
&:first-child,
&.shortpad {
padding-left: 8px;
}
&.scaledown {
> :global(*) {
zoom: 0.8;
}
}
}
}
.action {
color: var(--primary);
user-select: none;
cursor: pointer;
display: inline-block;
flex: 0 1 auto;
vertical-align: middle;
padding: 0 0.125rem;
}
.action.check {
transform: translateY(2px);
}
.action.disabled {
color: var(--gray);
cursor: inherit;
}
.badge {
background-color: $primary;
color: $menuBg;
font-size: 12px;
padding: 0.25em 0.5em;
border-radius: 50%;
box-sizing: border-box;
margin-right: 0.25em;
.action.scaledown > :global(*) {
zoom: 0.8;
}
@media only screen and (max-width: 720px) {
Expand Down
35 changes: 35 additions & 0 deletions src/pages/app/ActionBarContainer.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script lang="ts">
import { search, searchNext, searchPrev } from "../../search/search.js";
import { documents, unselectAll } from "../../manager/documents";
import { layout } from "../../manager/layout";
import { manager, selectAll } from "../../manager/manager";
import { orgsAndUsers } from "../../manager/orgsAndUsers";
import ActionBar from "./ActionBar.svelte";
$: loggedIn = $orgsAndUsers.loggedIn;
$: data = {
loading: $layout.loading,
documents: $documents.documents,
};
$: selection = {
checked: $layout.hasSelection,
indeterminate: $manager.someSelected,
editable: $layout.selectionEditable,
onCheck: selectAll,
onUncheck: unselectAll,
};
$: pagination = {
page: $search.page,
totalPages: $search.results?.numPages,
totalItems: $search.results?.count,
has_next: $search.hasNext,
has_prev: $search.hasPrev,
onNext: searchNext,
onPrev: searchPrev,
};
</script>

<ActionBar {loggedIn} {data} {selection} {pagination} />
2 changes: 1 addition & 1 deletion src/pages/app/Documents.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Components
import AddonStatus from "../../addons/progress/AddonStatus.svelte";
import ActionBar from "./ActionBar.svelte";
import ActionBar from "./ActionBarContainer.svelte";
import Anonymous from "./Anonymous.svelte";
import AccountNavigation from "./accounts/AccountNavigation.svelte";
import Button from "@/common/Button.svelte";
Expand Down
50 changes: 50 additions & 0 deletions src/pages/app/stories/ActionBar.stories.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<script context="module">
import { Story, Template } from "@storybook/addon-svelte-csf";
import { action } from "@storybook/addon-actions";
import ActionBar from "../ActionBar.svelte";
import documentFixture from "../../viewer/fixtures/document.json";
export const meta = {
title: "App / Action Bar",
component: ActionBar,
tags: ["autodocs"],
};
const args = {
loggedIn: true,
data: {
loading: false,
documents: [documentFixture, documentFixture, documentFixture],
},
selection: {
checked: false,
indeterminate: false,
editable: true,
onUncheck: action("Uncheck"),
onCheck: action("Check"),
},
pagination: {
page: 4,
totalPages: 12,
totalItems: 300,
has_next: true,
has_prev: true,
onNext: action("Next Page"),
onPrev: action("Prev Page"),
},
};
</script>

<Template let:args>
<ActionBar {...args} />
</Template>

<Story name="Default" {args} />
<Story
name="Not editable"
args={{
...args,
selection: { ...args.selection, editable: false, checked: true },
}}
/>

0 comments on commit 52c866b

Please sign in to comment.