@nascentdigital/funnel-editor 5.0.1 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components.d.ts +1 -0
- package/dist/components.js +1 -0
- package/dist/core/components/fields/OptInField.js +42 -2
- package/dist/core/components/fields/asset/AssetEditor.d.ts +1 -2
- package/dist/core/components/fields/asset/AssetEditor.js +18 -6
- package/dist/core/components/fields/asset/AssetUploader.d.ts +1 -2
- package/dist/core/components/fields/asset/AssetUploader.js +18 -6
- package/dist/core/components/fields/collection/CollectionEditor.d.ts +2 -1
- package/dist/core/components/fields/collection/CollectionEditor.js +17 -3
- package/dist/core/components/fields/embed/EmbeddedVideoEditor.d.ts +2 -2
- package/dist/core/components/fields/embed/EmbeddedVideoEditor.js +17 -5
- package/dist/core/components/fields/factories/AssetFactory.d.ts +3 -3
- package/dist/core/components/fields/factories/AssetFactory.js +18 -13
- package/dist/core/components/fields/factories/CollectionFactory.d.ts +3 -3
- package/dist/core/components/fields/factories/CollectionFactory.js +20 -13
- package/dist/core/components/fields/factories/EmbeddedVideoFactory.d.ts +3 -3
- package/dist/core/components/fields/factories/EmbeddedVideoFactory.js +17 -8
- package/dist/core/components/fields/factories/FieldValueFactory.d.ts +7 -5
- package/dist/core/components/fields/factories/FieldValueFactory.js +49 -12
- package/dist/core/components/fields/factories/LinkFactory.d.ts +3 -3
- package/dist/core/components/fields/factories/LinkFactory.js +17 -8
- package/dist/core/components/fields/factories/MediaFactory.d.ts +3 -3
- package/dist/core/components/fields/factories/MediaFactory.js +105 -149
- package/dist/core/components/fields/factories/ObjectFactory.d.ts +3 -2
- package/dist/core/components/fields/factories/ObjectFactory.js +16 -2
- package/dist/core/components/fields/factories/TextFactory.d.ts +3 -3
- package/dist/core/components/fields/factories/TextFactory.js +16 -10
- package/dist/core/components/fields/link/LinkEditor.d.ts +2 -2
- package/dist/core/components/fields/link/LinkEditor.js +18 -6
- package/dist/core/components/fields/media/MediaEditor.d.ts +2 -3
- package/dist/core/components/fields/media/MediaEditor.js +40 -11
- package/dist/core/components/fields/media/index.d.ts +0 -1
- package/dist/core/components/fields/media/index.js +0 -1
- package/dist/core/components/fields/object/ObjectEditor.d.ts +2 -1
- package/dist/core/components/fields/object/ObjectEditor.js +15 -1
- package/dist/core/components/interaction/Popup.d.ts +11 -7
- package/dist/core/components/interaction/Popup.js +8 -6
- package/dist/core/components/interaction/QuickInput.d.ts +2 -4
- package/dist/core/components/interaction/QuickInput.js +6 -2
- package/dist/core/components/interaction/menu/Menu.d.ts +8 -19
- package/dist/core/components/interaction/menu/Menu.js +26 -60
- package/dist/core/components/interaction/menu/useMenuController.d.ts +4 -2
- package/dist/core/components/interaction/menu/useMenuController.js +4 -1
- package/dist/core/domain/CollectionFieldProxy.js +1 -1
- package/dist/core/domain/Collections.js +0 -2
- package/dist/core/domain/ICollection.d.ts +1 -0
- package/dist/core/domain/IPage.d.ts +2 -1
- package/dist/core/domain/Site.js +0 -2
- package/dist/core/hooks/useCollectionRepository.d.ts +1 -1
- package/dist/core/hooks/useCollections.js +4 -0
- package/dist/core/hooks/usePageRepository.d.ts +1 -1
- package/dist/core/hooks/useSite.js +4 -0
- package/dist/core/repository/CollectionRepository.d.ts +2 -2
- package/dist/core/repository/ICollectionRepository.d.ts +2 -3
- package/dist/core/repository/SerializeCollectionUpdate.d.ts +5 -5
- package/dist/core/repository/SerializePageUpdate.d.ts +7 -8
- package/dist/core/splash/SplashContainer.d.ts +4 -2
- package/dist/core/splash/SplashContainer.js +3 -3
- package/dist/styles/index.css +8 -8
- package/package.json +2 -2
- package/dist/core/components/fields/media/MediaPicker.d.ts +0 -15
- package/dist/core/components/fields/media/MediaPicker.js +0 -251
|
@@ -17,6 +17,10 @@ function usePossibleCollections() {
|
|
|
17
17
|
if (!collections) {
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
|
+
// sync if it's not ready
|
|
21
|
+
else if (collections.state === 'uninitialized') {
|
|
22
|
+
collections.sync().catch(console.error);
|
|
23
|
+
}
|
|
20
24
|
// subscribe to changes
|
|
21
25
|
const subscription = collections.events$.subscribe(() => touch());
|
|
22
26
|
// unsubscribe on unmount
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { IPageRepository } from '../repository';
|
|
2
|
-
export declare function usePageRepository():
|
|
2
|
+
export declare function usePageRepository<TRepository extends IPageRepository = IPageRepository>(): TRepository;
|
|
3
3
|
export declare const PageRepositoryContext: import("react").Context<IPageRepository>;
|
|
@@ -17,6 +17,10 @@ function usePossibleSite() {
|
|
|
17
17
|
if (!site) {
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
|
+
// sync if it's not ready
|
|
21
|
+
else if (site.state === 'uninitialized') {
|
|
22
|
+
site.sync().catch(console.error);
|
|
23
|
+
}
|
|
20
24
|
// subscribe to changes
|
|
21
25
|
const subscription = site.events$.subscribe(() => touch());
|
|
22
26
|
// unsubscribe on unmount
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Schema } from '@nascentdigital/funnel-core';
|
|
2
2
|
import { UpdateCollectionCommand } from '../../api/collections';
|
|
3
3
|
import { EditorApiClient } from '../client';
|
|
4
|
-
import { Collection, CollectionFieldProxy } from '../domain';
|
|
4
|
+
import { Collection, CollectionFieldProxy, ICollection } from '../domain';
|
|
5
5
|
import { CollectionTarget } from './CollectionTarget';
|
|
6
6
|
import { ICollectionRepository } from './ICollectionRepository';
|
|
7
7
|
export declare class CollectionRepository implements ICollectionRepository {
|
|
@@ -26,5 +26,5 @@ export declare class CollectionRepository implements ICollectionRepository {
|
|
|
26
26
|
getItems(args: ICollectionRepository.GetItems.Args): Promise<ICollectionRepository.GetItems.Result>;
|
|
27
27
|
get(args: ICollectionRepository.Get.Args): Promise<ICollectionRepository.Get.Result>;
|
|
28
28
|
update(args: ICollectionRepository.Update.Args): Promise<ICollectionRepository.Update.Result>;
|
|
29
|
-
serializeUpdate(collection: Collection | CollectionFieldProxy, savables:
|
|
29
|
+
serializeUpdate(collection: Collection | CollectionFieldProxy, savables: ICollection.Savable[]): UpdateCollectionCommand.Data;
|
|
30
30
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CollectionClient } from '@nascentdigital/funnel-cms';
|
|
2
|
-
import { EventBus,
|
|
2
|
+
import { EventBus, Schema } from '@nascentdigital/funnel-core';
|
|
3
3
|
import { CollectionFieldProxy, ICollection } from '../domain';
|
|
4
4
|
export interface ICollectionRepository {
|
|
5
5
|
create(args: ICollectionRepository.Create.Args): Promise<ICollectionRepository.Create.Result>;
|
|
@@ -11,10 +11,9 @@ export interface ICollectionRepository {
|
|
|
11
11
|
getItems(args: ICollectionRepository.GetItems.Args): Promise<ICollectionRepository.GetItems.Result>;
|
|
12
12
|
get(args: ICollectionRepository.Get.Args): Promise<ICollectionRepository.Get.Result>;
|
|
13
13
|
update(args: ICollectionRepository.Update.Args): Promise<ICollectionRepository.Update.Result>;
|
|
14
|
-
serializeUpdate(collection: ICollection | CollectionFieldProxy, savables:
|
|
14
|
+
serializeUpdate(collection: ICollection | CollectionFieldProxy, savables: ICollection.Savable[]): ICollectionRepository.SerializeUpdates.Result;
|
|
15
15
|
}
|
|
16
16
|
export declare namespace ICollectionRepository {
|
|
17
|
-
type Savable = FieldModel;
|
|
18
17
|
namespace Create {
|
|
19
18
|
type Args = Omit<CollectionClient.Create.NewArgs, 'brand' | 'type' | 'version'> & {
|
|
20
19
|
template: Schema.Collection;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Field, FieldList, FieldModel, ObjectField, Schema } from '@nascentdigital/funnel-core';
|
|
2
|
-
import {
|
|
2
|
+
import { ICollection } from '../domain';
|
|
3
3
|
export declare namespace SerializeCollectionUpdate {
|
|
4
|
-
function serializeFieldsUpdate(updates: Schema.Collection.Update[], fields: ReadonlyArray<FieldModel>, parentPath: ReadonlyArray<string>, savables:
|
|
5
|
-
function serializeObjectFieldUpdate(updates: Schema.Collection.Update[], field: ObjectField, parentPath: ReadonlyArray<string>, savables:
|
|
6
|
-
function serializeFieldUpdate(updates: Schema.Collection.Update[], field: Field, parentPath: ReadonlyArray<string>, savables:
|
|
7
|
-
function serializeListUpdate(updates: Schema.Collection.Update[], list: FieldList, parentPath: ReadonlyArray<string>, savables:
|
|
4
|
+
function serializeFieldsUpdate(updates: Schema.Collection.Update[], fields: ReadonlyArray<FieldModel>, parentPath: ReadonlyArray<string>, savables: ICollection.Savable[]): Schema.Collection.Update[];
|
|
5
|
+
function serializeObjectFieldUpdate(updates: Schema.Collection.Update[], field: ObjectField, parentPath: ReadonlyArray<string>, savables: ICollection.Savable[]): void;
|
|
6
|
+
function serializeFieldUpdate(updates: Schema.Collection.Update[], field: Field, parentPath: ReadonlyArray<string>, savables: ICollection.Savable[]): void;
|
|
7
|
+
function serializeListUpdate(updates: Schema.Collection.Update[], list: FieldList, parentPath: ReadonlyArray<string>, savables: ICollection.Savable[]): void;
|
|
8
8
|
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { Field, FieldList, FieldModel, ObjectField, Schema } from '@nascentdigital/funnel-core';
|
|
2
|
-
import
|
|
2
|
+
import { Block, IPage, Section } from '../domain';
|
|
3
3
|
export declare namespace SerializePageUpdate {
|
|
4
|
-
|
|
5
|
-
function
|
|
6
|
-
function
|
|
7
|
-
function
|
|
8
|
-
function
|
|
9
|
-
function
|
|
10
|
-
function serializeListUpdate(updates: Schema.Page.Update[], list: FieldList, parentPath: ReadonlyArray<string>, savables: Savable[]): void;
|
|
4
|
+
function serializeSectionUpdate(updates: Schema.Page.Update[], section: Section, parentPath: string, savables: IPage.Savable[]): void;
|
|
5
|
+
function serializeBlockUpdate(updates: Schema.Page.Update[], block: Block, parentPath: string, savables: IPage.Savable[]): void;
|
|
6
|
+
function serializeFieldsUpdate(updates: Schema.Page.Update[], fields: ReadonlyArray<FieldModel>, parentPath: ReadonlyArray<string>, savables: IPage.Savable[]): Schema.Page.Update[];
|
|
7
|
+
function serializeObjectFieldUpdate(updates: Schema.Page.Update[], field: ObjectField, parentPath: ReadonlyArray<string>, savables: IPage.Savable[]): void;
|
|
8
|
+
function serializeFieldUpdate(updates: Schema.Page.Update[], field: Field, parentPath: ReadonlyArray<string>, savables: IPage.Savable[]): void;
|
|
9
|
+
function serializeListUpdate(updates: Schema.Page.Update[], list: FieldList, parentPath: ReadonlyArray<string>, savables: IPage.Savable[]): void;
|
|
11
10
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
|
2
|
-
export declare function SplashContainer({ children }: SplashContainer.Props): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function SplashContainer({ message, children }: SplashContainer.Props): import("react/jsx-runtime").JSX.Element;
|
|
3
3
|
export declare namespace SplashContainer {
|
|
4
|
-
type Props = PropsWithChildren
|
|
4
|
+
type Props = PropsWithChildren & {
|
|
5
|
+
message?: string;
|
|
6
|
+
};
|
|
5
7
|
}
|
|
@@ -8,16 +8,16 @@ const Splash_1 = require("./Splash");
|
|
|
8
8
|
const SplashContext_1 = require("./SplashContext");
|
|
9
9
|
const SplashService_1 = require("./SplashService");
|
|
10
10
|
// component
|
|
11
|
-
function SplashContainer({ children }) {
|
|
11
|
+
function SplashContainer({ message = 'Signing you in', children }) {
|
|
12
12
|
// bind hooks + memo
|
|
13
13
|
const service = (0, react_2.useMemo)(() => {
|
|
14
14
|
// create service
|
|
15
15
|
const service = new SplashService_1.SplashService();
|
|
16
16
|
// start in a loading state
|
|
17
|
-
service.showLoading(
|
|
17
|
+
service.showLoading(message);
|
|
18
18
|
// return service
|
|
19
19
|
return service;
|
|
20
|
-
}, []);
|
|
20
|
+
}, [message]);
|
|
21
21
|
const [context, setContext] = (0, react_2.useState)(() => ({ service }));
|
|
22
22
|
// update context on event changes
|
|
23
23
|
(0, react_2.useEffect)(() => {
|
package/dist/styles/index.css
CHANGED
|
@@ -501,10 +501,10 @@ video {
|
|
|
501
501
|
}
|
|
502
502
|
|
|
503
503
|
[popover]{
|
|
504
|
-
inset: var(--toolwind-toggle-
|
|
505
|
-
background-color: var(--toolwind-toggle-
|
|
506
|
-
color: var(--toolwind-toggle-
|
|
507
|
-
margin: var(--toolwind-toggle-
|
|
504
|
+
inset: var(--toolwind-toggle-oQHJpc9jXV, 0px);
|
|
505
|
+
background-color: var(--toolwind-toggle-GCBdFMAuDL, canvas);
|
|
506
|
+
color: var(--toolwind-toggle-I8FwR2AIO0, canvastext);
|
|
507
|
+
margin: var(--toolwind-toggle-irGpFytKLG, auto);
|
|
508
508
|
}
|
|
509
509
|
html, body, #__next, .Editor-wrap{
|
|
510
510
|
position: relative;
|
|
@@ -5996,10 +5996,10 @@ img.nd-Visual-image {
|
|
|
5996
5996
|
.anchored\/\[--nd-popup-anchor\]:where(.anchored\/\[--nd-popup-anchor\]){
|
|
5997
5997
|
position: absolute;
|
|
5998
5998
|
view-transition-name: --tw-anchor-view-transition-2j1919322s193433343934192p322r2w33362l;
|
|
5999
|
-
--toolwind-toggle-
|
|
6000
|
-
--toolwind-toggle-
|
|
6001
|
-
--toolwind-toggle-
|
|
6002
|
-
--toolwind-toggle-
|
|
5999
|
+
--toolwind-toggle-oQHJpc9jXV: auto;
|
|
6000
|
+
--toolwind-toggle-GCBdFMAuDL: transparent;
|
|
6001
|
+
--toolwind-toggle-I8FwR2AIO0: inherit;
|
|
6002
|
+
--toolwind-toggle-irGpFytKLG: 0px;
|
|
6003
6003
|
}
|
|
6004
6004
|
.counter-l1{
|
|
6005
6005
|
counter-reset: l1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nascentdigital/funnel-editor",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "restricted"
|
|
@@ -91,5 +91,5 @@
|
|
|
91
91
|
"ts-jest": "^29",
|
|
92
92
|
"type-fest": "^4"
|
|
93
93
|
},
|
|
94
|
-
"gitHead": "
|
|
94
|
+
"gitHead": "24d9690cf813052f6561c3ccef11c7cf69ad7f7c"
|
|
95
95
|
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { Language, Schema } from '@nascentdigital/funnel-core';
|
|
2
|
-
import { ICollection } from '../../../domain';
|
|
3
|
-
export declare const MediaPicker: import("react").ForwardRefExoticComponent<MediaPicker.Props & import("react").RefAttributes<MediaPicker.Ref>>;
|
|
4
|
-
export declare namespace MediaPicker {
|
|
5
|
-
type Props = {
|
|
6
|
-
language: Language;
|
|
7
|
-
};
|
|
8
|
-
interface Ref {
|
|
9
|
-
pick(options?: Options): Promise<Result>;
|
|
10
|
-
}
|
|
11
|
-
type Options = {
|
|
12
|
-
schema: Schema.CollectionField;
|
|
13
|
-
};
|
|
14
|
-
type Result = ICollection.Ref | undefined;
|
|
15
|
-
}
|
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.MediaPicker = void 0;
|
|
7
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
-
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
9
|
-
const classnames_1 = __importDefault(require("classnames"));
|
|
10
|
-
const framer_motion_1 = require("framer-motion");
|
|
11
|
-
const react_1 = require("react");
|
|
12
|
-
const hooks_1 = require("../../../hooks");
|
|
13
|
-
const feedback_1 = require("../../feedback");
|
|
14
|
-
const interaction_1 = require("../../interaction");
|
|
15
|
-
const transitions_1 = require("../../transitions");
|
|
16
|
-
// component
|
|
17
|
-
exports.MediaPicker = (0, react_1.forwardRef)(function MediaPicker({ language }, ref) {
|
|
18
|
-
// bind props + hooks
|
|
19
|
-
const [deferral, setDeferral] = (0, react_1.useState)(undefined);
|
|
20
|
-
const [result, setResult] = (0, react_1.useState)();
|
|
21
|
-
const [schema, setSchema] = (0, react_1.useState)();
|
|
22
|
-
const [collectionGroups, setCollectionGroups] = (0, react_1.useState)();
|
|
23
|
-
const [collectionGroup, setCollectionGroup] = (0, react_1.useState)();
|
|
24
|
-
const [collections, setCollections] = (0, react_1.useState)();
|
|
25
|
-
const [tagOptions, setTagOptions] = (0, react_1.useState)();
|
|
26
|
-
const [tagFilters, setTagFilters] = (0, react_1.useState)([]);
|
|
27
|
-
const [tagTooltip, setTagTooltip] = (0, react_1.useState)();
|
|
28
|
-
const [fetching, setFetching] = (0, react_1.useState)(false);
|
|
29
|
-
const [error, setError] = (0, react_1.useState)();
|
|
30
|
-
const repo = (0, hooks_1.useCollectionRepository)();
|
|
31
|
-
const siteCollections = (0, hooks_1.useCollections)();
|
|
32
|
-
const collectionStore = (0, hooks_1.useCollectionStore)();
|
|
33
|
-
// export service
|
|
34
|
-
(0, react_1.useImperativeHandle)(ref, () => ({
|
|
35
|
-
pick: async ({ schema }) => {
|
|
36
|
-
// reset state
|
|
37
|
-
setSchema(schema);
|
|
38
|
-
setCollectionGroups(undefined);
|
|
39
|
-
setCollectionGroup(undefined);
|
|
40
|
-
setTagOptions(undefined);
|
|
41
|
-
setTagFilters([]);
|
|
42
|
-
setTagTooltip(undefined);
|
|
43
|
-
setCollections(undefined);
|
|
44
|
-
setError(undefined);
|
|
45
|
-
// create deferral
|
|
46
|
-
const deferral = new funnel_core_1.Deferral();
|
|
47
|
-
setDeferral(deferral);
|
|
48
|
-
setResult(undefined);
|
|
49
|
-
// wait until deferral is resolved
|
|
50
|
-
return deferral.promise;
|
|
51
|
-
}
|
|
52
|
-
}), []);
|
|
53
|
-
// fetch collection groups when schema changes
|
|
54
|
-
(0, react_1.useEffect)(() => {
|
|
55
|
-
// skip if there's no deferral
|
|
56
|
-
if (!schema || !deferral) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
// reset error (if any)
|
|
60
|
-
setError(undefined);
|
|
61
|
-
// sync site
|
|
62
|
-
siteCollections.sync()
|
|
63
|
-
// bind groups, filtering out types that aren't part of the set
|
|
64
|
-
.then(() => {
|
|
65
|
-
// determine group list
|
|
66
|
-
const { collections } = schema;
|
|
67
|
-
const collectionGroups = collections.length === 0
|
|
68
|
-
? siteCollections.items
|
|
69
|
-
: siteCollections.items
|
|
70
|
-
.filter(group => collections.some(collection => collection.type === group.type));
|
|
71
|
-
setCollectionGroups(collectionGroups);
|
|
72
|
-
// bind first group as in initial selection
|
|
73
|
-
const [collectionGroup] = collectionGroups;
|
|
74
|
-
setCollectionGroup(collectionGroup);
|
|
75
|
-
// short-circuit collections if none are present
|
|
76
|
-
if (!collectionGroup) {
|
|
77
|
-
setCollections([]);
|
|
78
|
-
setTagOptions([]);
|
|
79
|
-
setTagFilters([]);
|
|
80
|
-
}
|
|
81
|
-
})
|
|
82
|
-
// handle error
|
|
83
|
-
.catch(e => {
|
|
84
|
-
console.error('[MediaPicker/sync] sync failed', e);
|
|
85
|
-
setError(feedback_1.ErrorMessage.coerce(e));
|
|
86
|
-
});
|
|
87
|
-
}, [siteCollections, deferral, schema]);
|
|
88
|
-
// fetch collection items when group changes
|
|
89
|
-
(0, react_1.useEffect)(() => {
|
|
90
|
-
// ignore if not ready
|
|
91
|
-
if (!collectionGroup) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
console.debug('[MediaPicker/sync] syncing group', collectionGroup);
|
|
95
|
-
// clear collections
|
|
96
|
-
setCollections(undefined);
|
|
97
|
-
setTagOptions(undefined);
|
|
98
|
-
setTagFilters([]);
|
|
99
|
-
// sync group
|
|
100
|
-
collectionGroup.sync()
|
|
101
|
-
// then update filters
|
|
102
|
-
.then(() => {
|
|
103
|
-
// transform items
|
|
104
|
-
const collections = collectionGroup.items
|
|
105
|
-
.map(summary => summary.getClosestCollectionRef(language, collectionGroup.defaultLanguage))
|
|
106
|
-
.filter(funnel_core_1.Value.isDefined);
|
|
107
|
-
// set collections
|
|
108
|
-
setCollections(collections);
|
|
109
|
-
// setup tags (if there are items in group)
|
|
110
|
-
if (collections.length > 0) {
|
|
111
|
-
const { tags: tagGroups } = collectionGroup.template;
|
|
112
|
-
const tagOptions = tagGroups
|
|
113
|
-
.map(tagGroup => {
|
|
114
|
-
// get all tags in group
|
|
115
|
-
const tags = Object.values(tagGroup.tags).reduce((tags, tag) => {
|
|
116
|
-
// add tag if it matches
|
|
117
|
-
if (collections.some(collection => collection.tags.includes(tag))) {
|
|
118
|
-
tags.add(tag);
|
|
119
|
-
}
|
|
120
|
-
// keep reducing
|
|
121
|
-
return tags;
|
|
122
|
-
}, new Set());
|
|
123
|
-
// create filter group (if there are items)
|
|
124
|
-
return tags.size > 0
|
|
125
|
-
? { group: tagGroup, tags }
|
|
126
|
-
: undefined;
|
|
127
|
-
})
|
|
128
|
-
.filter(funnel_core_1.Value.isDefined);
|
|
129
|
-
// set options
|
|
130
|
-
setTagOptions(tagOptions);
|
|
131
|
-
}
|
|
132
|
-
// or clear tags
|
|
133
|
-
else {
|
|
134
|
-
setTagOptions([]);
|
|
135
|
-
}
|
|
136
|
-
})
|
|
137
|
-
// or capture error
|
|
138
|
-
.catch(e => setError(feedback_1.ErrorMessage.coerce(e)));
|
|
139
|
-
}, [language, collectionGroup]);
|
|
140
|
-
// helpers
|
|
141
|
-
const onPick = async (collectionRef) => {
|
|
142
|
-
// clear tooltips
|
|
143
|
-
setTagTooltip(undefined);
|
|
144
|
-
// fetch ref (or fail)
|
|
145
|
-
const { template, id, name } = collectionRef;
|
|
146
|
-
const collection = await repo.get({ id, version: 'draft' });
|
|
147
|
-
if (!collection) {
|
|
148
|
-
setFetching(false);
|
|
149
|
-
setError({
|
|
150
|
-
title: `Unable to find ${template.name}`,
|
|
151
|
-
message: `We ran into an issue while trying to fetch the "${name}" collection item. Please refresh your browser and try again.`
|
|
152
|
-
});
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
// add collection
|
|
156
|
-
collectionStore.addCollection(collection.data);
|
|
157
|
-
// set result (triggers picker to close)
|
|
158
|
-
setResult(collectionRef);
|
|
159
|
-
};
|
|
160
|
-
const onCancel = () => {
|
|
161
|
-
// clear tooltips
|
|
162
|
-
setTagTooltip(undefined);
|
|
163
|
-
// set result (triggers picker to close)
|
|
164
|
-
setResult(null);
|
|
165
|
-
};
|
|
166
|
-
const onPickerClosed = () => {
|
|
167
|
-
// skip if missing or already completed
|
|
168
|
-
if (!deferral || deferral.isComplete) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
// complete deferral
|
|
172
|
-
deferral.resolve(result !== null && result !== void 0 ? result : undefined);
|
|
173
|
-
};
|
|
174
|
-
// render
|
|
175
|
-
return ((0, jsx_runtime_1.jsxs)(interaction_1.Picker, { className: "flex", open: deferral && result === undefined, disableDismiss: fetching, onClose: onCancel, onClosed: onPickerClosed, children: [(0, jsx_runtime_1.jsxs)("section", { className: "shrink-0 w-[206px] flex flex-col gap-l8 p-l8 bg-modal-background", children: [(0, jsx_runtime_1.jsx)("h1", { className: "heading-md text-content-primary", children: "Select Collection" }), (0, jsx_runtime_1.jsx)(interaction_1.ChipFilters, { title: "Site Collections", options: collectionGroups, selectedOptions: collectionGroup && [collectionGroup], onToggle: (collectionGroup, selected) => selected && setCollectionGroup(collectionGroup), renderLabel: collectionGroup => collectionGroup.template.name, disabled: fetching })] }), (0, jsx_runtime_1.jsxs)("section", { className: "flex-1 flex flex-col", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 p-l8 overflow-y-scroll", tabIndex: -1, children: (0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { mode: "wait", initial: false, children: renderPicker({ language, error, collectionGroups, collectionGroup, collections, tagOptions, tagFilters, onPick, setTagTooltip, fetching }) }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex justify-end items-center p-l8 border-t border-solid border-border-l1", children: (0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "secondary", size: "sm", onClick: onCancel, disabled: fetching, children: "Cancel" }) }), (0, jsx_runtime_1.jsx)(interaction_1.Popup, { className: (0, classnames_1.default)('max-w-[200px] bg-surface2 rounded-md p-l5', 'border border-solid border-border-l1 shadow-tooltip', 'flex flex-wrap items-center gap-l4'), open: !!tagTooltip, anchor: tagTooltip === null || tagTooltip === void 0 ? void 0 : tagTooltip.anchor, anchorOffset: 4, placement: "top", disableOverlay: true, onClose: () => setTagTooltip(undefined), children: tagTooltip === null || tagTooltip === void 0 ? void 0 : tagTooltip.tags.map(tag => (0, jsx_runtime_1.jsx)(feedback_1.Badge, { variant: "outlinedTiny", status: "draft", label: tag.name }, tag.data)) })] })] }));
|
|
176
|
-
});
|
|
177
|
-
function renderPicker({ language, schema, error, collectionGroups, collectionGroup, collections, tagOptions, tagFilters, onPick, setTagTooltip, fetching }) {
|
|
178
|
-
// show error if we have one
|
|
179
|
-
if (error) {
|
|
180
|
-
return ((0, jsx_runtime_1.jsx)(transitions_1.FadeIn, { className: "flex flex-col justify-center items-center", children: (0, jsx_runtime_1.jsx)(feedback_1.ErrorMessage, { error: error }) }, "error"));
|
|
181
|
-
}
|
|
182
|
-
// or show loader if filters aren't loaded (or if fetching)
|
|
183
|
-
else if (fetching || !collectionGroups || !collections || !tagOptions) {
|
|
184
|
-
return ((0, jsx_runtime_1.jsx)(transitions_1.FadeIn, { className: "w-full h-full flex flex-col justify-center items-center", children: (0, jsx_runtime_1.jsx)(interaction_1.Loader, { size: "lg" }) }, "loader"));
|
|
185
|
-
}
|
|
186
|
-
// show empty state if there are no pages
|
|
187
|
-
else if (!collectionGroup || collections.length === 0) {
|
|
188
|
-
return ((0, jsx_runtime_1.jsx)(transitions_1.FadeIn, { className: "h-full flex flex-wrap justify-center items-center", children: (0, jsx_runtime_1.jsxs)(feedback_1.EmptyState, { variant: "missing", size: "sm", children: [(0, jsx_runtime_1.jsx)("p", { className: "body-md text-content-secondary text-pretty", children: "There are no collections available that match your criteria." }), (0, jsx_runtime_1.jsx)("p", { className: "body-md text-content-secondary text-pretty", children: "Create a new collection." })] }) }, "pages.empty"));
|
|
189
|
-
}
|
|
190
|
-
// or show pages (filtered)
|
|
191
|
-
else {
|
|
192
|
-
// get tags that are available (no tags at all means "all" of the group is chosen)
|
|
193
|
-
const collectionSchema = collectionGroup.template;
|
|
194
|
-
const schemaTags = collectionSchema.tags.flatMap(tagGroup => Object.values(tagGroup.tags));
|
|
195
|
-
const activeTagFilters = tagFilters.filter(tag => schemaTags.includes(tag));
|
|
196
|
-
const tags = tagOptions
|
|
197
|
-
.filter(({ group }) => collectionSchema.tags.includes(group))
|
|
198
|
-
.flatMap(({ tags }) => {
|
|
199
|
-
const filteredTags = activeTagFilters.filter(tag => tags.has(tag));
|
|
200
|
-
return filteredTags.length > 0 ? filteredTags : tags.values().toArray();
|
|
201
|
-
});
|
|
202
|
-
const filteredCollections = activeTagFilters.length > 0
|
|
203
|
-
? collections.filter(collection => collection.tags.some(tag => tags.includes(tag)))
|
|
204
|
-
: collections;
|
|
205
|
-
// render empty list if there are no items
|
|
206
|
-
if (filteredCollections.length === 0) {
|
|
207
|
-
return ((0, jsx_runtime_1.jsx)(transitions_1.FadeIn, { className: "h-full flex flex-col items-center justify-center gap-l5 px-l10", variant: "blur", children: (0, jsx_runtime_1.jsx)("p", { className: "body-md text-content-secondary text-pretty", children: "Sorry, but no collections match your filters." }) }, "pages.dyanmic.empty"));
|
|
208
|
-
}
|
|
209
|
-
// or render items
|
|
210
|
-
else {
|
|
211
|
-
return ((0, jsx_runtime_1.jsx)(transitions_1.FadeIn, { className: "flex flex-col gap-l3", children: filteredCollections.map(ref => renderCollectionRef({
|
|
212
|
-
language,
|
|
213
|
-
template: ref.template,
|
|
214
|
-
ref,
|
|
215
|
-
onPick,
|
|
216
|
-
setTagTooltip
|
|
217
|
-
})) }, "pages.dynamic"));
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
function renderCollectionRef({ language, template, ref, onPick, setTagTooltip }) {
|
|
222
|
-
var _a;
|
|
223
|
-
// resolve props
|
|
224
|
-
const title = (_a = ref.name) !== null && _a !== void 0 ? _a : template.name;
|
|
225
|
-
const tags = ref ? ref.tags : [];
|
|
226
|
-
const visibleTags = tags.slice(0, Math.min(tags.length, 2));
|
|
227
|
-
const tooltipTags = tags.length > 2
|
|
228
|
-
? tags.slice(2)
|
|
229
|
-
: [];
|
|
230
|
-
const disabled = ref.language !== language;
|
|
231
|
-
// helpers
|
|
232
|
-
const onClick = () => {
|
|
233
|
-
// ignore if disabled
|
|
234
|
-
if (disabled) {
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
// otherwise, pick
|
|
238
|
-
else {
|
|
239
|
-
onPick(ref);
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
|
-
// render
|
|
243
|
-
const anchorId = `col-pick-tip-${ref.id}`;
|
|
244
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('flex items-center px-l7 py-l4 select-none interpolate', 'even:bg-modal-background rounded-md', {
|
|
245
|
-
'hover:bg-modal-surface2/tint2 cursor-pointer': !disabled,
|
|
246
|
-
'cursor-default': disabled
|
|
247
|
-
}), onClick: onClick, tabIndex: disabled ? undefined : 0, children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)('w-full flex items-center gap-l8 select-none interpolate', {
|
|
248
|
-
'opacity-disabled': disabled
|
|
249
|
-
}), onClick: onClick, children: [(0, jsx_runtime_1.jsx)("h3", { className: "flex-1 label-sm text-content-primary ellipsis", children: title }), tags.length > 0 &&
|
|
250
|
-
(0, jsx_runtime_1.jsxs)("div", { className: "shrink-0 flex items-center gap-l4", children: [visibleTags.map(tag => (0, jsx_runtime_1.jsx)(feedback_1.Badge, { variant: "outlinedTiny", status: "draft", label: tag.name }, tag.data)), tooltipTags.length > 0 && ((0, jsx_runtime_1.jsx)(feedback_1.Badge, { anchorId: anchorId, variant: "outlinedTiny", status: "draft", label: `+${tooltipTags.length}`, onPointerEnter: e => setTagTooltip({ anchor: anchorId, tags: tooltipTags }), onPointerLeave: () => setTagTooltip(undefined) }))] })] }) }, ref.id));
|
|
251
|
-
}
|