Skip to content

Commit

Permalink
feat: finalize guideline actions (#293)
Browse files Browse the repository at this point in the history
  • Loading branch information
GoranRibic authored and SamuelAlev committed Dec 9, 2022
1 parent b25ebbe commit 3205f68
Show file tree
Hide file tree
Showing 17 changed files with 546 additions and 195 deletions.
5 changes: 5 additions & 0 deletions .changeset/blue-toys-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@frontify/app-bridge": patch
---

Added more guideline actions
11 changes: 11 additions & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"mode": "pre",
"tag": "beta",
"initialVersions": {
"@frontify/app-bridge": "3.0.0-beta.31",
"@frontify/frontify-cli": "5.3.3",
"@frontify/guideline-blocks-settings": "0.25.5",
"@frontify/sidebar-settings": "0.0.8"
},
"changesets": []
}
111 changes: 80 additions & 31 deletions packages/app-bridge/src/AppBridgeTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import {
createCoverPage,
createDocument,
createDocumentCategory,
createDocumentGroup,
createDocumentPage,
deleteCoverPage,
deleteDocument,
deleteDocumentCategory,
deleteDocumentGroup,
deleteDocumentPage,
getBrandportalLink,
Expand All @@ -19,37 +21,43 @@ import {
getDocumentSectionsByDocumentPageId,
getDocumentsWithoutDocumentGroupByProjectId,
getUncategorizedPagesByDocumentId,
publishCoverPage,
updateBrandportalLink,
updateCoverPage,
updateDocument,
updateDocumentCategory,
updateDocumentGroup,
updateDocumentPage,
updateLegacyCoverPage,
} from './repositories';

import type {
import {
BrandportalLink,
Color,
ColorPalette,
CoverPage,
CoverPageCreate,
CreateDocumentGroup,
CreateDocumentLibrary,
CreateDocumentLink,
CreateDocumentPage,
CreateDocumentStandard,
CoverPageUpdate,
CoverPageUpdateLegacy,
Document,
DocumentCategory,
DocumentCategoryCreate,
DocumentCategoryUpdate,
DocumentGroup,
DocumentGroupCreate,
DocumentGroupUpdate,
DocumentLibrary,
DocumentLibraryCreate,
DocumentLibraryUpdate,
DocumentLink,
DocumentLinkCreate,
DocumentLinkUpdate,
DocumentPage,
DocumentPageCreate,
DocumentPageUpdate,
DocumentSection,
UpdateDocumentGroup,
UpdateDocumentLibrary,
UpdateDocumentLink,
UpdateDocumentPage,
UpdateDocumentStandard,
DocumentStandardCreate,
DocumentStandardUpdate,
LinkType,
} from './types';
import { getDatasetByElement } from './utilities';

Expand All @@ -76,60 +84,101 @@ export class AppBridgeTheme {
return getDatasetByElement<{ translationLanguage?: string }>(document.body).translationLanguage ?? '';
}

public async createLink(link: CreateDocumentLink) {
return createDocument<DocumentLink>(link as DocumentLink);
public async createLink(link: DocumentLinkCreate) {
return createDocument<DocumentLink>({
...link,
linkType: LinkType.External,
portalId: this.getPortalId(),
} as DocumentLink);
}

public async updateLink(link: UpdateDocumentLink) {
public async updateLink(link: DocumentLinkUpdate) {
return updateDocument<DocumentLink>(link as DocumentLink);
}

public async deleteLink(id: number) {
return deleteDocument(id);
}

public async createLibrary(library: CreateDocumentLibrary) {
return createDocument<DocumentLibrary>(library as DocumentLibrary);
public async createLibrary(library: DocumentLibraryCreate) {
return createDocument<DocumentLibrary>({
...library,
portalId: this.getPortalId(),
settings: { project: library.settings?.project ?? this.getProjectId() },
} as DocumentLibrary);
}

public async updateLibrary(library: UpdateDocumentLibrary) {
public async updateLibrary(library: DocumentLibraryUpdate) {
return updateDocument<DocumentLibrary>(library as DocumentLibrary);
}

public async deleteLibrary(id: number) {
return deleteDocument(id);
}

public async createStandardDocument(document: CreateDocumentStandard) {
return createDocument<Document>(document as Document);
public async createStandardDocument(document: DocumentStandardCreate) {
return createDocument<Document>({ ...document, portalId: this.getPortalId() } as Document);
}

public async updateStandardDocument(document: UpdateDocumentStandard) {
public async updateStandardDocument(document: DocumentStandardUpdate) {
return updateDocument<Document>(document as Document);
}

public async deleteStandardDocument(id: number) {
return deleteDocument(id);
}

public async createDocumentGroup(documentGroup: CreateDocumentGroup) {
return createDocumentGroup(documentGroup as DocumentGroup);
public async createDocumentGroup(documentGroup: DocumentGroupCreate) {
return createDocumentGroup({ ...documentGroup, portalId: this.getPortalId() } as DocumentGroup);
}

public async updateDocumentGroup(documentGroup: UpdateDocumentGroup) {
public async updateDocumentGroup(documentGroup: DocumentGroupUpdate) {
return updateDocumentGroup(documentGroup as DocumentGroup);
}

public async deleteDocumentGroup(id: number) {
return deleteDocumentGroup(id);
}

public async createDocumentPage(documentPage: CreateDocumentPage) {
return createDocumentPage(documentPage as DocumentPage);
public async createDocumentCategory(category: DocumentCategoryCreate) {
return createDocumentCategory(category as DocumentCategory);
}

public async updateDocumentPage(documentPage: UpdateDocumentPage) {
return updateDocumentPage(documentPage as DocumentPage);
public async updateDocumentCategory(category: DocumentCategoryUpdate) {
return updateDocumentCategory(category as DocumentCategory);
}

public async deleteDocumentCategory(id: number) {
return deleteDocumentCategory(id);
}

public async createDocumentPage(documentPage: DocumentPageCreate) {
return createDocumentPage({
...documentPage,
...(documentPage.linkUrl && { linkType: LinkType.External }),
} as DocumentPage);
}

/**
* A method for page update
*
* @param documentPage - {@link DocumentPageUpdate} object
* @requires id - Indicates page identifier.
*
*
* and at least one of
*
* @property title - Indicates title of a page.
* @property documentId - Indicates to witch document the page belongs to.
* @property categoryId - Indicates to witch category the page belongs to.
* @property visibility - Indicates whether the page is visible only to the editor or everyone.
* @property linkUrl - Indicates whether the page is link or not.
*/
public async updateDocumentPage(documentPage: DocumentPageUpdate) {
return updateDocumentPage({
...documentPage,
...(documentPage.linkUrl && { linkType: LinkType.External }),
} as DocumentPage);
}

public async deleteDocumentPage(id: number) {
Expand All @@ -140,15 +189,15 @@ export class AppBridgeTheme {
return createCoverPage(coverPage as CoverPage);
}

public async updateCoverPage(coverPage: CoverPage) {
public async updateCoverPage(coverPage: CoverPageUpdate) {
return updateCoverPage(coverPage as CoverPage);
}

/**
* @deprecated legacy method, should be removed once new endpoint is available
*/
public async publishCoverPage(coverPage: { brandhome_draft: boolean }) {
return publishCoverPage({ ...coverPage, portalId: this.getPortalId() });
public async updateLegacyCoverPage(coverPage: CoverPageUpdateLegacy) {
return updateLegacyCoverPage({ ...coverPage, portalId: this.getPortalId() });
}

public async deleteCoverPage() {
Expand Down
10 changes: 10 additions & 0 deletions packages/app-bridge/src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,14 @@

type Nullable<T> = T | null;

/**
Type that behaves just like RequiredExactlyOne from type-fest with only difference that the remaining keys are set to optional.
@category Object
*/
type RequireOnlyOne<ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> = {
[Key in KeysType]: Required<Pick<ObjectType, Key>> & Partial<Record<Exclude<KeysType, Key>, never>>;
}[KeysType] &
Partial<Omit<ObjectType, KeysType>>;

type PickRequired<Type, Key extends keyof Type> = Type & Required<Pick<Type, Key>>;
88 changes: 73 additions & 15 deletions packages/app-bridge/src/react/useDocumentPages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,27 @@ export const useDocumentPages = (appBridge: AppBridgeTheme, documentId: number)
}, [appBridge, documentId]);

useEffect(() => {
const updatePageFromEvent = (event: { page: DocumentPage; action: EmitterAction }) => {
const updatePageFromEvent = (event: { page: DocumentPage | DocumentCategory; action: EmitterAction }) => {
setDocumentPages((previousState) => {
if (event.action === 'add') {
return previousState ? [...cloneDeep(previousState), event.page] : [event.page];
const isInitial = previousState === null;

if (isInitial) {
return event.action === 'update' || event.action === 'add' ? [event.page] : previousState;
}

if (event.action === 'delete') {
return previousState
? cloneDeep(previousState).filter((page) => page.id !== event.page.id)
: previousState;
return deletePage(previousState, event.page);
}

const pageToUpdateIndex = previousState?.findIndex((page) => page.id === event.page.id);

if (!pageToUpdateIndex || previousState === null) {
return previousState;
if (event.action === 'add') {
return addPage(previousState, event.page, documentId);
}

const stateClone = cloneDeep(previousState);

stateClone[pageToUpdateIndex] = event.page;
if (event.action === 'update') {
return updatePage(previousState, event.page);
}

return stateClone;
return previousState;
});
};

Expand All @@ -57,7 +55,67 @@ export const useDocumentPages = (appBridge: AppBridgeTheme, documentId: number)
return () => {
window.emitter.off('AppBridge:GuidelineDocumentPageUpdate', updatePageFromEvent);
};
}, [appBridge]);
}, [appBridge, documentId]);

return [documentPages];
};

const addPage = (
pages: (DocumentPage | DocumentCategory)[],
pageToAdd: DocumentPage | DocumentCategory,
currentDocument: number,
) => {
if (pageToAdd.documentId !== currentDocument) {
return pages;
}

const pagesClone = cloneDeep(pages);

const isPageInCategory =
'categoryId' in pageToAdd && pageToAdd.categoryId !== null && pageToAdd.categoryId !== undefined;

const addPageToCategory = () => {
for (const page of pagesClone) {
if (
page.id === (pageToAdd as DocumentPage).categoryId &&
page.documentId === pageToAdd.documentId &&
'documentPages' in page
) {
page.documentPages
? page.documentPages.push(pageToAdd as DocumentPage)
: (page.documentPages = [pageToAdd as DocumentPage]);

break;
}
}
};

isPageInCategory ? addPageToCategory() : pagesClone.push(pageToAdd);

return pagesClone;
};

const updatePage = (
documents: (DocumentPage | DocumentCategory)[],
documentToUpdate: DocumentPage | DocumentCategory,
) => {
const pagesClone = cloneDeep(documents);

const documentToUpdateIndex = pagesClone.findIndex((document) => document.id === documentToUpdate.id);

pagesClone[documentToUpdateIndex] = documentToUpdate;

return pagesClone;
};

const deletePage = (pages: (DocumentPage | DocumentCategory)[], pageToDelete: { id: number }) => {
const filteredPages = pages.filter((page) => page.id !== pageToDelete.id);

return filteredPages.map((page) => {
if ('documentPages' in page) {
page.documentPages = page.documentPages.filter((page) => page.id !== pageToDelete.id);
}

return page;
});
};
Loading

0 comments on commit 3205f68

Please sign in to comment.