5.42.2 • Published 3 months ago

@webiny/app-aco v5.42.2

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

@webiny/app-aco

npm.io npm.io code style: prettier PRs Welcome

A set of frontend aco-related utilities.

Table of Contents

Installation

npm install --save @webiny/app-aco

Or if you prefer yarn:

yarn add @webiny/app-aco

Overview

The @webiny/app-aco package contains essential aco-related utilities (Advanced Content Organisation), that can be used within a React app. These include the FoldersProvider provider component, the useFolders and useRecords hooks, which can be used to retrieve the current folder and search record information and interact with them.

ℹ️ INFO

Internally, the FoldersProvider provider retrieves information from the Webiny's default GraphQL API. Because of this, note that this project relies on @webiny/api-aco when it comes to retrieving folders and records information (via GraphQL).

Reference

Components

ACOProvider

export declare const ACOProvider: React.ComponentType;

The ACOProvider is a provider component, which retrieves the folders and records information. The component also makes it possible to use the useFolders and useRecords hook, which can be used to list, create, update or delete folders and records within the React app.

import React from "react";
import { ACOProvider } from "@webiny/app-aco";

export const App = () => {
  return (
    <ACOProvider>
      <MyApp />
    </ACOProvider>
  );
};

FolderTree

import { NodeModel } from "@minoru/react-dnd-treeview";
import { DndItemData } from "~/types";

interface Props {
    type: string;
    title: string;
    enableCreate?: boolean;
    enableActions?: boolean;
    focusedFolderId?: string;
    hiddenFolderId?: string;
    onFolderClick: (data: NodeModel<DndItemData>["data"]) => void;
    onTitleClick?: (event: React.MouseEvent<HTMLElement>) => void;
}

declare function FolderTree(props: Props): React.ComponentType;

FolderTree component shows the tree list of folders for a particular type.

import React from "react";
import { FolderTree } from "@webiny/app-aco";

export const MyComponent = () => {
    return (
        <FolderTree
            type={"page"}
            title={"All pages"}
            enableCreate={true}
            enableActions={true}
            focusedFolderId={"anyExistingId"}
            hiddenFolderId={"folderIdToHide"}
            onFolderClick={item => console.log(item)}
            onTitleClick={() => console.log("Do whatever you like on title click")}
        />
    );
};

ℹ️ INFO

Internally, the FolderTree uses react-dnd-treeview to render and manage the folder list: DO NOT rely on any of this package features, we might change it in the future.

EntryDialogMove

import { DialogOnClose } from "@webiny/ui/Dialog";
import { SearchRecordItem } from "@webiny/app-aco";

interface Props {
    type: string;
    searchRecord: SearchRecordItem;
    open: boolean;
    onClose: DialogOnClose;
}

declare function EntryDialogMove(props: Props): React.ComponentType;

EntryDialogMove component shows a dialog to allow users to move a search record into a folder.

import React, { useState } from "react";
import { EntryDialogMove } from "@webiny/app-aco";

type Props = {
    searchRecord: SearchRecordItem;
}

export const MyComponent = ({ searchRecord }: Props) => {
    const [dialogOpen, setDialogOpen] = useState(false);
    
    return (
        <>
            <button onClick={() => setDialogOpen(true)}>Edit folder</button>
            <EntryDialogMove
                type={"anyType"}
                searchRecord={searchRecord}
                open={dialogOpen}
                onClose={() => setDialogOpen(false)}
            />
        </>
    );
};

FolderDialogCreate

import { DialogOnClose } from "@webiny/ui/Dialog";

interface Props {
    type: string;
    open: boolean;
    onClose: DialogOnClose;
    currentParentId?: string | null;
}

declare function FolderDialogCreate(props: Props): React.ComponentType;

FolderDialogCreate component shows a dialog to allow users to create a new folder.

import React, { useState } from "react";
import { FolderDialogCreate } from "@webiny/app-aco";

export const MyComponent = () => {
    const [dialogOpen, setDialogOpen] = useState(false);
    
    return (
        <>
            <button onClick={() => setDialogOpen(true)}>Create folder</button>
            <FolderDialogCreate
                type={"page"}
                open={dialogOpen}
                onClose={() => setDialogOpen(false)}
                currentParentId={"anyParentId"}
            />
        </>
    );
};

FolderDialogDelete

import { DialogOnClose } from "@webiny/ui/Dialog";

interface Props {
    folder: FolderItem;
    open: boolean;
    onClose: DialogOnClose;
}

declare function FolderDialogDelete(props: Props): React.ComponentType;

FolderDialogDelete component shows a dialog to allow users to delete an existing folder.

import React, { useState } from "react";
import { FolderDialogDelete } from "@webiny/app-aco";

type Props = {
    folder: FolderItem;
}

export const MyComponent = ({ folder }: Props) => {
    const [dialogOpen, setDialogOpen] = useState(false);
    
    return (
        <>
            <button onClick={() => setDialogOpen(true)}>Delete folder</button>
            <FolderDialogDelete
                folder={folder}
                open={dialogOpen}
                onClose={() => setDialogOpen(false)}
            />
        </>
    );
};

FolderDialogUpdate

import { DialogOnClose } from "@webiny/ui/Dialog";

interface Props {
    folder: FolderItem;
    open: boolean;
    onClose: DialogOnClose;
}

declare function FolderDialogUpdate(props: Props): React.ComponentType;

FolderDialogUpdate component shows a dialog to allow users to update an existing folder.

import React, { useState } from "react";
import { FolderDialogUpdate } from "@webiny/app-aco";

type Props = {
    folder: FolderItem;
}

export const MyComponent = ({ folder }: Props) => {
    const [dialogOpen, setDialogOpen] = useState(false);
    
    return (
        <>
            <button onClick={() => setDialogOpen(true)}>Edit folder</button>
            <FolderDialogUpdate
                folder={folder}
                open={dialogOpen}
                onClose={() => setDialogOpen(false)}
            />
        </>
    );
};

Hooks

useFolders

import {FolderItem, FoldersActions} from "./types";

interface UseFoldersHook {
    folders: FolderItem[];
    loading: Record<FoldersActions, boolean>;
    getFolder: (id: string) => Promise<FolderItem>;
    createFolder: (folder: Omit<FolderItem, "id">) => Promise<FolderItem>;
    updateFolder: (folder: FolderItem) => Promise<FolderItem>;
    deleteFolder(folder: FolderItem): Promise<true>;
}

export declare function useFolders(type: string): UseFoldersHook;

useFolders hook allows you to interact with folders state and related APIs while building your custom component.

import React from "react";
import { useFolders } from "@webiny/app-aco";

export const MyComponent = () => {
    const { folders } = useFolders("page");
    
    if (folders) {
        return folders.map(folder => {
            return <span key={folder.id}>{folder.name}</span>;
        });
    }
    
    return <span>No folders to show</span>;
};

As you might notice, there is not listFolders method available from useFolders() hook: this is because on first mount, listFolders is called internally, which will either issue a network request, or load folders from cache.

You don't need to store the result of it to any local state; that is managed by the context provider.

useRecords

import { SearchRecordItem, Loading, LoadingActions, ListMeta } from "./types";

interface UseRecordsHook {
    records: SearchRecordItem[];
    loading: Loading<LoadingActions>;
    meta: Meta<ListMeta>;
    listRecords: (params: {
        type?: string;
        folderId?: string;
        limit?: number;
        after?: string;
        sort?: ListSort;
    }) => Promise<SearchRecordItem[]>;
    getRecord: (id: string) => Promise<SearchRecordItem>;
    createRecord: (record: Omit<SearchRecordItem, "id">) => Promise<SearchRecordItem>;
    updateRecord: (record: SearchRecordItem, contextFolderId?: string) => Promise<SearchRecordItem>;
    deleteRecord(record: SearchRecordItem): Promise<true>;
}

export declare function useRecords(type: string, folderId: string): UseRecordsHook;

useRecords() hook allows you to interact with search records state and related APIs while building your custom component.

import React, { useEffect, useState } from "react";
import { useRecords } from "@webiny/app-aco";

import { getEntryDetails } from "./any-custom-hook"

export const MyComponent = () => {
    const { records } = useRecords("anyType", "anyFolderId");
    const [entries, setEntries] = useState([]);
    
    useEffect(() => {
        const details = getEntryDetails(records);
        setEntries(details)
    }, [records])
    
    if (entries) {
        return entries.map(entry => {
            return <span key={entry.id}>{entry.title}</span>;
        });
    }
    
    return <span>No entries to show</span>;
};

You don't need to store the result of it to any local state; that is managed by the context provider.

5.42.2

3 months ago

5.42.2-beta.4

3 months ago

5.42.2-beta.5

3 months ago

5.42.2-beta.2

3 months ago

5.42.2-beta.3

3 months ago

5.42.2-beta.1

3 months ago

5.42.1

4 months ago

5.42.1-beta.3

4 months ago

5.42.2-beta.0

4 months ago

5.42.1-beta.2

4 months ago

5.42.1-beta.1

4 months ago

5.41.5-beta.3

4 months ago

5.40.9

4 months ago

5.42.1-beta.0

4 months ago

5.41.5-beta.2

5 months ago

5.40.9-beta.0

4 months ago

5.42.0

5 months ago

5.42.0-beta.4

5 months ago

5.42.0-beta.3

5 months ago

5.42.0-beta.2

5 months ago

5.42.0-beta.1

5 months ago

5.41.5-beta.1

5 months ago

5.41.5-beta.0

5 months ago

5.40.8

5 months ago

5.42.0-beta.0

5 months ago

5.40.8-beta.1

6 months ago

5.41.4

6 months ago

5.40.8-beta.0

6 months ago

5.41.4-beta.6

6 months ago

5.41.4-beta.5

6 months ago

5.41.4-beta.4

6 months ago

5.41.4-beta.3

6 months ago

5.41.4-beta.2

6 months ago

5.41.3-beta.0

7 months ago

5.41.3-beta.1

7 months ago

5.41.3-beta.2

7 months ago

5.40.7-beta.0

7 months ago

5.41.4-beta.1

7 months ago

5.41.2-beta.1

7 months ago

5.40.7

7 months ago

5.41.2

7 months ago

5.41.3

7 months ago

5.41.2-beta.0

7 months ago

5.41.1-beta.4

8 months ago

5.41.1

8 months ago

5.41.1-beta.3

8 months ago

5.41.1-beta.1

8 months ago

5.41.1-beta.2

8 months ago

5.41.1-beta.0

8 months ago

5.41.0-beta.3

8 months ago

5.41.0

8 months ago

5.41.0-beta.2

8 months ago

5.41.0-beta.1

8 months ago

5.41.0-beta.0

8 months ago

5.40.6-beta.2

9 months ago

5.40.6-beta.3

9 months ago

5.40.6

9 months ago

5.40.6-beta.0

9 months ago

5.40.6-beta.1

9 months ago

5.41.0-dbt.0

9 months ago

5.39.12-beta.2

9 months ago

5.39.12-beta.1

9 months ago

5.39.12-beta.0

9 months ago

5.39.14-beta.0

9 months ago

5.39.11

10 months ago

5.39.13

9 months ago

5.39.12

9 months ago

5.39.15

9 months ago

5.39.14

9 months ago

5.39.13-beta.0

9 months ago

5.39.15-beta.0

9 months ago

5.40.5-beta.0

10 months ago

5.39.10

10 months ago

5.40.5

10 months ago

5.39.11-beta.0

10 months ago

5.39.11-beta.1

10 months ago

5.39.10-beta.2

10 months ago

5.39.10-beta.1

10 months ago

5.39.10-beta.0

10 months ago

5.39.9

10 months ago

5.39.9-beta.1

10 months ago

5.40.4-beta.1

11 months ago

5.40.4-beta.2

11 months ago

5.40.4

11 months ago

5.40.4-beta.0

11 months ago

5.40.3

11 months ago

5.40.3-beta.0

11 months ago

5.40.3-beta.1

11 months ago

5.39.8

1 year ago

5.39.9-beta.0

12 months ago

5.40.0-beta.6

12 months ago

5.40.2-beta.0

11 months ago

5.40.2-beta.1

11 months ago

6.0.0-beta.0

12 months ago

5.40.1-beta.1

12 months ago

5.40.1-beta.2

12 months ago

5.40.1-beta.0

12 months ago

5.40.1

12 months ago

5.40.2

11 months ago

5.40.0

12 months ago

5.39.7

1 year ago

5.39.8-beta.0

1 year ago

5.39.7-beta.5

1 year ago

5.39.7-beta.4

1 year ago

5.39.7-beta.2

1 year ago

5.39.7-beta.3

1 year ago

5.40.0-beta.5

1 year ago

5.40.0-beta.4

1 year ago

5.40.0-beta.3

1 year ago

5.39.7-beta.1

1 year ago

5.39.7-beta.0

1 year ago

5.39.6

1 year ago

5.39.6-beta.1

1 year ago

5.39.6-beta.0

1 year ago

5.39.5

1 year ago

5.39.5-beta.1

1 year ago

5.40.0-beta.2

1 year ago

5.40.0-beta.1

1 year ago

5.39.4

1 year ago

5.39.4-beta.1

1 year ago

5.40.0-beta.0

1 year ago

5.39.4-beta.0

1 year ago

5.39.3

1 year ago

5.39.3-beta.0

1 year ago

5.39.3-beta.1

1 year ago

5.39.2

1 year ago

5.39.2-beta.2

1 year ago

5.39.2-beta.3

1 year ago

5.39.2-beta.1

1 year ago

5.39.2-beta.0

1 year ago

5.38.6

1 year ago

5.39.1

1 year ago

5.39.1-beta.1

1 year ago

5.39.0

1 year ago

5.39.1-beta.0

1 year ago

5.39.0-beta.2

1 year ago

5.39.0-beta.3

1 year ago

5.38.5-beta.0

1 year ago

5.38.5

1 year ago

5.38.4

1 year ago

5.38.4-beta.0

1 year ago

5.38.3-beta.1

1 year ago

5.38.3

1 year ago

5.38.3-beta.0

1 year ago

5.38.2

2 years ago

5.38.2-beta.0

2 years ago

5.37.2-beta.3

2 years ago

5.37.2-beta.2

2 years ago

5.39.0-beta.0

2 years ago

5.39.0-beta.1

2 years ago

5.38.0-beta.0

2 years ago

5.37.1-beta.3

2 years ago

5.37.1-beta.1

2 years ago

5.37.1-beta.2

2 years ago

5.37.3-beta.0

2 years ago

5.37.1-beta.0

2 years ago

5.37.6-beta.0

2 years ago

5.37.5-beta.0

2 years ago

5.37.3-beta.1

2 years ago

5.37.2-beta.1

2 years ago

5.37.6-beta.1

2 years ago

5.37.3-beta.2

2 years ago

5.37.2-beta.0

2 years ago

5.37.5-beta.1

2 years ago

5.37.4-beta.1

2 years ago

5.37.4-beta.0

2 years ago

5.37.8-beta.0

2 years ago

5.37.7-beta.0

2 years ago

5.38.0-beta.5

2 years ago

5.38.0-beta.6

2 years ago

5.38.0-beta.3

2 years ago

5.38.0-beta.4

2 years ago

5.38.0-beta.1

2 years ago

5.38.0-beta.2

2 years ago

5.38.1-beta.0

2 years ago

5.37.0-beta.3

2 years ago

5.37.0-beta.2

2 years ago

5.37.0-beta.1

2 years ago

5.37.7

2 years ago

5.37.8

2 years ago

5.37.5

2 years ago

5.37.6

2 years ago

5.37.3

2 years ago

5.37.4

2 years ago

5.37.1

2 years ago

5.37.2

2 years ago

5.37.0

2 years ago

5.34.9-beta.0

2 years ago

5.38.0

2 years ago

5.38.1

2 years ago

5.36.2

2 years ago

5.36.2-beta.2

2 years ago

5.36.2-beta.1

2 years ago

5.37.0-beta.0

2 years ago

5.36.2-beta.0

2 years ago

5.35.4

2 years ago

5.35.4-beta.1

2 years ago

5.35.4-beta.0

2 years ago

5.35.3

2 years ago

5.36.1

2 years ago

5.36.1-beta.1

2 years ago

5.36.1-beta.0

2 years ago

5.35.3-beta.0

2 years ago

5.36.0

2 years ago

5.36.0-beta.2

2 years ago

5.36.0-beta.1

2 years ago

5.36.0-beta.0

2 years ago

5.35.2

2 years ago

5.35.2-beta.0

2 years ago

5.35.1

2 years ago

5.35.1-beta.0

2 years ago

5.35.0

2 years ago

5.35.0-beta.2

2 years ago

5.35.0-beta.1

2 years ago

5.35.0-beta.0

2 years ago

5.34.8

2 years ago

5.34.8-beta.1

2 years ago

5.34.8-beta.0

2 years ago

5.34.7

2 years ago

5.34.7-beta.2

2 years ago

5.34.7-beta.1

2 years ago

5.34.7-beta.0

2 years ago

5.34.6

2 years ago

5.34.6-beta.6

2 years ago

5.34.6-beta.5

2 years ago

5.34.6-beta.4

2 years ago

5.34.6-beta.3

2 years ago

5.34.6-beta.2

2 years ago

5.34.6-beta.1

2 years ago

5.34.6-beta.0

2 years ago

5.34.5

2 years ago

5.34.5-beta.1

2 years ago

5.34.5-beta.0

2 years ago

5.34.4

2 years ago

5.34.4-beta.0

2 years ago

5.34.3

2 years ago

5.34.3-beta.3

2 years ago

5.34.3-beta.2

2 years ago

5.34.3-beta.1

2 years ago

5.34.3-beta.0

2 years ago

5.34.2

2 years ago

5.34.2-beta.2

2 years ago

5.34.2-beta.1

2 years ago

5.34.2-beta.0

2 years ago

5.34.1

2 years ago

5.34.1-beta.3

2 years ago

5.34.1-beta.2

2 years ago

5.34.1-beta.1

2 years ago

5.34.1-beta.0

2 years ago

5.34.0

2 years ago

5.34.0-beta.2

2 years ago

5.34.0-beta.1

2 years ago

5.34.0-beta.0

2 years ago