From 3266dbb23ab9c972d5a82d2788b36c6704f1cd96 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 20 Jun 2024 09:35:02 +0000 Subject: [PATCH 01/29] chore(release): set `package.json` to 1.0.0-next.2 [skip ci] # [1.0.0-next.2](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-next.1...v1.0.0-next.2) (2024-06-20) ### Bug Fixes * endpoints for connect ([f35f853](https://github.com/powerhouse-inc/document-model-electron/commit/f35f8532e14475e74cc80119e5df0274f2b5f1e7)) * semantic release ([1ccdf9e](https://github.com/powerhouse-inc/document-model-electron/commit/1ccdf9e6cbcaa9de8c9a51627311f94a032a039a)) ### Features * added addpublicdrive util ([123ed8b](https://github.com/powerhouse-inc/document-model-electron/commit/123ed8be07321eafcac2521f4ae7452e86a6895f)) * added cypress CI config ([e50fb06](https://github.com/powerhouse-inc/document-model-electron/commit/e50fb062eccf6387399bad9403f59a20bc478d89)) * added Cypress Cloud Config ([3439c54](https://github.com/powerhouse-inc/document-model-electron/commit/3439c5493098d66a6e7563068f35afcae255b142)) * added cypress setup ([be8e1b6](https://github.com/powerhouse-inc/document-model-electron/commit/be8e1b6e702f3f9209d694d5642ee82465a6bb9b)) * added develop environment ([c33ab9d](https://github.com/powerhouse-inc/document-model-electron/commit/c33ab9d6977712a3015d28a0cd27208f7fd727e5)) * added develop to release cycle ([b9247e6](https://github.com/powerhouse-inc/document-model-electron/commit/b9247e66d19ffc9400caae9403d9b5b06048eacc)) * added reload Connect toast ([944b086](https://github.com/powerhouse-inc/document-model-electron/commit/944b0866bf7ca830581a21ed828f81c880891922)) * added version comparison ([85661ea](https://github.com/powerhouse-inc/document-model-electron/commit/85661eaa9aac0a8f38ce465adf1c0c227a442846)) * avoid recreate fileOptions and clickOptionsHandler for each file node ([0a0ef3a](https://github.com/powerhouse-inc/document-model-electron/commit/0a0ef3a181489ec91a8c8439f25dcb9f3713f9a9)) * avoid recreate folderOptions and clickFolderOptionsHandler for each folder node ([6329b29](https://github.com/powerhouse-inc/document-model-electron/commit/6329b291adee5895070f3b2192f84c36c86406a8)) * bump libs ([e9d7a4f](https://github.com/powerhouse-inc/document-model-electron/commit/e9d7a4f40f16bc9a50d1191d04d4c0d3e8f54ad4)) * bump libs ([32b2f39](https://github.com/powerhouse-inc/document-model-electron/commit/32b2f390eee0d613b86b4988e970db27077868c3)) * bump libs ([1216c33](https://github.com/powerhouse-inc/document-model-electron/commit/1216c33f4c713d4c7ac6eeb76725a51a6e6cf9a0)) * bump libs ([153909c](https://github.com/powerhouse-inc/document-model-electron/commit/153909c5c7e0bc2c97511f9001c1b3e4f7ec5f79)) * bump libs ([fe4d49a](https://github.com/powerhouse-inc/document-model-electron/commit/fe4d49a4acdccb5a24678ca38b914257599a63b9)) * enabled sync icons for folders and files ([9336e8a](https://github.com/powerhouse-inc/document-model-electron/commit/9336e8a3d1c818a962b5c0d0ef108ab07c2d3872)) * handle empty string as parent folder ([3260ccb](https://github.com/powerhouse-inc/document-model-electron/commit/3260ccbcd0b1b4b188a7881d8881fae604bbf8f3)) * moved isAllowedToCreateDocuments to folderView ([8af8020](https://github.com/powerhouse-inc/document-model-electron/commit/8af8020109d85cd1d6cae167cd51ddf722d2bb46)) * re-use decodedDriveID ([1a82d60](https://github.com/powerhouse-inc/document-model-electron/commit/1a82d60b5bbfc5f99f99d38e3909da4364325817)) * removed debug code ([4aa9c4c](https://github.com/powerhouse-inc/document-model-electron/commit/4aa9c4c2fa205a2f2823d2816b64e420efe2cf2a)) * updated design-system alpha 119 ([c27a968](https://github.com/powerhouse-inc/document-model-electron/commit/c27a968f2bfd745d48a7a69a451d4c18e72acdf9)) * updated document-drive ([cce5625](https://github.com/powerhouse-inc/document-model-electron/commit/cce5625d5392f3860a2f5b71ad144dd99d98ebda)) * updated libs ([5edef9d](https://github.com/powerhouse-inc/document-model-electron/commit/5edef9d1d1936f3bb7c9006c180c7a352f8d6bb9)) * updated release script ([639b2a5](https://github.com/powerhouse-inc/document-model-electron/commit/639b2a50405d32f884f941457702ba12a6fa3a6b)) * use memoized version of FileItem component ([040c2b6](https://github.com/powerhouse-inc/document-model-electron/commit/040c2b6ca0cdd8c87d313d27169213a50cffb4cd)) ### Performance Improvements * decode id only one when getting readable item path ([5c019b9](https://github.com/powerhouse-inc/document-model-electron/commit/5c019b951db04c31e8f2f163fd32a4e465eb3264)) * implemented scalable way to compare drive state ([5b4f360](https://github.com/powerhouse-inc/document-model-electron/commit/5b4f360f9be815e52131f56fedf3f6a97e77ed7f)) --- CHANGELOG.md | 43 +++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e01d3521..7dfe5a4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,46 @@ +# [1.0.0-next.2](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-next.1...v1.0.0-next.2) (2024-06-20) + + +### Bug Fixes + +* endpoints for connect ([f35f853](https://github.com/powerhouse-inc/document-model-electron/commit/f35f8532e14475e74cc80119e5df0274f2b5f1e7)) +* semantic release ([1ccdf9e](https://github.com/powerhouse-inc/document-model-electron/commit/1ccdf9e6cbcaa9de8c9a51627311f94a032a039a)) + + +### Features + +* added addpublicdrive util ([123ed8b](https://github.com/powerhouse-inc/document-model-electron/commit/123ed8be07321eafcac2521f4ae7452e86a6895f)) +* added cypress CI config ([e50fb06](https://github.com/powerhouse-inc/document-model-electron/commit/e50fb062eccf6387399bad9403f59a20bc478d89)) +* added Cypress Cloud Config ([3439c54](https://github.com/powerhouse-inc/document-model-electron/commit/3439c5493098d66a6e7563068f35afcae255b142)) +* added cypress setup ([be8e1b6](https://github.com/powerhouse-inc/document-model-electron/commit/be8e1b6e702f3f9209d694d5642ee82465a6bb9b)) +* added develop environment ([c33ab9d](https://github.com/powerhouse-inc/document-model-electron/commit/c33ab9d6977712a3015d28a0cd27208f7fd727e5)) +* added develop to release cycle ([b9247e6](https://github.com/powerhouse-inc/document-model-electron/commit/b9247e66d19ffc9400caae9403d9b5b06048eacc)) +* added reload Connect toast ([944b086](https://github.com/powerhouse-inc/document-model-electron/commit/944b0866bf7ca830581a21ed828f81c880891922)) +* added version comparison ([85661ea](https://github.com/powerhouse-inc/document-model-electron/commit/85661eaa9aac0a8f38ce465adf1c0c227a442846)) +* avoid recreate fileOptions and clickOptionsHandler for each file node ([0a0ef3a](https://github.com/powerhouse-inc/document-model-electron/commit/0a0ef3a181489ec91a8c8439f25dcb9f3713f9a9)) +* avoid recreate folderOptions and clickFolderOptionsHandler for each folder node ([6329b29](https://github.com/powerhouse-inc/document-model-electron/commit/6329b291adee5895070f3b2192f84c36c86406a8)) +* bump libs ([e9d7a4f](https://github.com/powerhouse-inc/document-model-electron/commit/e9d7a4f40f16bc9a50d1191d04d4c0d3e8f54ad4)) +* bump libs ([32b2f39](https://github.com/powerhouse-inc/document-model-electron/commit/32b2f390eee0d613b86b4988e970db27077868c3)) +* bump libs ([1216c33](https://github.com/powerhouse-inc/document-model-electron/commit/1216c33f4c713d4c7ac6eeb76725a51a6e6cf9a0)) +* bump libs ([153909c](https://github.com/powerhouse-inc/document-model-electron/commit/153909c5c7e0bc2c97511f9001c1b3e4f7ec5f79)) +* bump libs ([fe4d49a](https://github.com/powerhouse-inc/document-model-electron/commit/fe4d49a4acdccb5a24678ca38b914257599a63b9)) +* enabled sync icons for folders and files ([9336e8a](https://github.com/powerhouse-inc/document-model-electron/commit/9336e8a3d1c818a962b5c0d0ef108ab07c2d3872)) +* handle empty string as parent folder ([3260ccb](https://github.com/powerhouse-inc/document-model-electron/commit/3260ccbcd0b1b4b188a7881d8881fae604bbf8f3)) +* moved isAllowedToCreateDocuments to folderView ([8af8020](https://github.com/powerhouse-inc/document-model-electron/commit/8af8020109d85cd1d6cae167cd51ddf722d2bb46)) +* re-use decodedDriveID ([1a82d60](https://github.com/powerhouse-inc/document-model-electron/commit/1a82d60b5bbfc5f99f99d38e3909da4364325817)) +* removed debug code ([4aa9c4c](https://github.com/powerhouse-inc/document-model-electron/commit/4aa9c4c2fa205a2f2823d2816b64e420efe2cf2a)) +* updated design-system alpha 119 ([c27a968](https://github.com/powerhouse-inc/document-model-electron/commit/c27a968f2bfd745d48a7a69a451d4c18e72acdf9)) +* updated document-drive ([cce5625](https://github.com/powerhouse-inc/document-model-electron/commit/cce5625d5392f3860a2f5b71ad144dd99d98ebda)) +* updated libs ([5edef9d](https://github.com/powerhouse-inc/document-model-electron/commit/5edef9d1d1936f3bb7c9006c180c7a352f8d6bb9)) +* updated release script ([639b2a5](https://github.com/powerhouse-inc/document-model-electron/commit/639b2a50405d32f884f941457702ba12a6fa3a6b)) +* use memoized version of FileItem component ([040c2b6](https://github.com/powerhouse-inc/document-model-electron/commit/040c2b6ca0cdd8c87d313d27169213a50cffb4cd)) + + +### Performance Improvements + +* decode id only one when getting readable item path ([5c019b9](https://github.com/powerhouse-inc/document-model-electron/commit/5c019b951db04c31e8f2f163fd32a4e465eb3264)) +* implemented scalable way to compare drive state ([5b4f360](https://github.com/powerhouse-inc/document-model-electron/commit/5b4f360f9be815e52131f56fedf3f6a97e77ed7f)) + # 1.0.0-next.1 (2024-06-18) diff --git a/package.json b/package.json index 9e8c0af5..1a5a75d3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@powerhousedao/connect", "productName": "Powerhouse-Connect", - "version": "1.0.0-next.1", + "version": "1.0.0-next.2", "description": "Powerhouse Connect", "main": ".vite/build/main.js", "license": "AGPL-3.0-only", From f1d41255e92c16d0d56365246c2538c45c3540c8 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 24 Jun 2024 12:14:14 +0000 Subject: [PATCH 02/29] chore(release): set `package.json` to 1.0.0-next.3 [skip ci] # [1.0.0-next.3](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-next.2...v1.0.0-next.3) (2024-06-24) ### Bug Fixes * remove resulting state from cache ([4d8c6fe](https://github.com/powerhouse-inc/document-model-electron/commit/4d8c6feef417c9254e12a9aac0c58d7769d34d84)) ### Features * added virtualization for files content ([f8e9093](https://github.com/powerhouse-inc/document-model-electron/commit/f8e9093d72a8db79338c68220f09a83d4e7ea2be)) * bump libs ([b3d7fa9](https://github.com/powerhouse-inc/document-model-electron/commit/b3d7fa9e0e9c52b12d5671f3db77425a6b343e9e)) --- CHANGELOG.md | 13 +++++++++++++ package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dfe5a4b..4c59f51a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# [1.0.0-next.3](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-next.2...v1.0.0-next.3) (2024-06-24) + + +### Bug Fixes + +* remove resulting state from cache ([4d8c6fe](https://github.com/powerhouse-inc/document-model-electron/commit/4d8c6feef417c9254e12a9aac0c58d7769d34d84)) + + +### Features + +* added virtualization for files content ([f8e9093](https://github.com/powerhouse-inc/document-model-electron/commit/f8e9093d72a8db79338c68220f09a83d4e7ea2be)) +* bump libs ([b3d7fa9](https://github.com/powerhouse-inc/document-model-electron/commit/b3d7fa9e0e9c52b12d5671f3db77425a6b343e9e)) + # [1.0.0-next.2](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-next.1...v1.0.0-next.2) (2024-06-20) diff --git a/package.json b/package.json index 75641289..c3a3494b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@powerhousedao/connect", "productName": "Powerhouse-Connect", - "version": "1.0.0-next.2", + "version": "1.0.0-next.3", "description": "Powerhouse Connect", "main": ".vite/build/main.js", "license": "AGPL-3.0-only", From 2e5d77fdfd0cab9794563ef70e88954c9b99c73f Mon Sep 17 00:00:00 2001 From: ryanwolhuter Date: Mon, 1 Jul 2024 12:28:45 +0200 Subject: [PATCH 03/29] feat: update query Signed-off-by: ryanwolhuter --- src/utils/getSwitchboardUrl.ts | 97 ++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/src/utils/getSwitchboardUrl.ts b/src/utils/getSwitchboardUrl.ts index 225afdb9..3708551e 100644 --- a/src/utils/getSwitchboardUrl.ts +++ b/src/utils/getSwitchboardUrl.ts @@ -1,50 +1,55 @@ const rwaQuery = `... on RealWorldAssets { - state { - accounts { - id - reference - label - } - principalLenderAccountId - spvs { - id - name - } - serviceProviderFeeTypes { - id - name - feeType - accountId - } - fixedIncomeTypes { - id - name - } - portfolio { - ... on FixedIncome { - id - spvId - ISIN - CUSIP - coupon - } - ... on Cash { - id - spvId - currency - } - } - transactions { - type - entryTime - cashBalanceChange - feeTransactions { - id - amount - tradeTime - } - } - } + state { + portfolio { + __typename + ... on FixedIncome { + name + CUSIP + purchaseDate + purchasePrice + purchaseProceeds + salesProceeds + totalDiscount + spvId + } + ... on Cash { + id + balance + } + } + transactions { + id + type + entryTime + cashBalanceChange + fees { + id + serviceProviderFeeTypeId + amount + } + txRef + cashTransaction { + id + assetId + amount + entryTime + tradeTime + settlementTime + accountId + counterPartyAccountId + } + fixedIncomeTransaction { + id + assetId + amount + entryTime + tradeTime + settlementTime + accountId + counterPartyAccountId + } + } + } }`; const accountSnapshot = `... on AccountSnapshot { From f85b07677c5ea3f73940440259099aef5536d165 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 1 Jul 2024 10:33:40 +0000 Subject: [PATCH 04/29] chore(release): set `package.json` to 1.0.0-next.4 [skip ci] # [1.0.0-next.4](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-next.3...v1.0.0-next.4) (2024-07-01) ### Features * update query ([2e5d77f](https://github.com/powerhouse-inc/document-model-electron/commit/2e5d77fdfd0cab9794563ef70e88954c9b99c73f)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c59f51a..d1f900ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [1.0.0-next.4](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-next.3...v1.0.0-next.4) (2024-07-01) + + +### Features + +* update query ([2e5d77f](https://github.com/powerhouse-inc/document-model-electron/commit/2e5d77fdfd0cab9794563ef70e88954c9b99c73f)) + # [1.0.0-next.3](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-next.2...v1.0.0-next.3) (2024-06-24) diff --git a/package.json b/package.json index c3a3494b..39adf094 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@powerhousedao/connect", "productName": "Powerhouse-Connect", - "version": "1.0.0-next.3", + "version": "1.0.0-next.4", "description": "Powerhouse Connect", "main": ".vite/build/main.js", "license": "AGPL-3.0-only", From edd9bfc1f1914c13855343d77b6fc8029df6f737 Mon Sep 17 00:00:00 2001 From: Guillermo Puente Date: Mon, 8 Jul 2024 15:08:50 -0400 Subject: [PATCH 05/29] feat: reload default drives when config has been updated --- src/hooks/useLoadDefaultDrives.ts | 64 +++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/src/hooks/useLoadDefaultDrives.ts b/src/hooks/useLoadDefaultDrives.ts index 6b0064b9..8d82418e 100644 --- a/src/hooks/useLoadDefaultDrives.ts +++ b/src/hooks/useLoadDefaultDrives.ts @@ -1,19 +1,65 @@ import { useEffect, useRef } from 'react'; import { useDocumentDriveServer } from './useDocumentDriveServer'; import { useFeatureFlag } from './useFeatureFlags'; +import defaultConfig from './useFeatureFlags/default-config'; + +type DefaultDrive = { + url: string; + loaded: boolean; +}; + +const areLoadedDrivesUpToDate = ( + defaultDrivesConfig: DefaultDrive[], + loadedDrives: DefaultDrive[], +) => { + for (const defaultDrive of defaultDrivesConfig) { + const loadedDrive = loadedDrives.find( + loadedDrive => loadedDrive.url === defaultDrive.url, + ); + + if (!loadedDrive) { + return false; + } + } + + return true; +}; export const useLoadDefaultDrives = () => { const loadingDrives = useRef([]); - const { addRemoteDrive, documentDrives, documentDrivesStatus } = - useDocumentDriveServer(); + const { + addRemoteDrive, + documentDrives, + documentDrivesStatus, + clearStorage, + } = useDocumentDriveServer(); const { setConfig, config: { defaultDrives }, } = useFeatureFlag(); + async function resetDefaultDrive() { + await clearStorage(); + setConfig(defaultConfig); + location.reload(); + loadingDrives.current = []; + } + useEffect(() => { if (!defaultDrives) return; + // reset default drives if config has been updated + if ( + loadingDrives.current.length <= 0 && + defaultDrives.every(drive => drive.loaded) && + defaultConfig.defaultDrives && + defaultConfig.defaultDrives.length > 0 && + !areLoadedDrivesUpToDate(defaultConfig.defaultDrives, defaultDrives) + ) { + void resetDefaultDrive(); + return; + } + for (const defaultDrive of defaultDrives) { if ( documentDrivesStatus === 'LOADED' && @@ -26,7 +72,19 @@ export const useLoadDefaultDrives = () => { ); }); - if (isDriveAlreadyAdded) return; + if (isDriveAlreadyAdded) { + setConfig(conf => ({ + ...conf, + defaultDrives: [ + ...(conf.defaultDrives || []).filter( + drive => drive.url !== defaultDrive.url, + ), + { ...defaultDrive, loaded: true }, + ], + })); + + return; + } loadingDrives.current.push(defaultDrive.url); From 631bcc36fafaa9fe8502820d9ac872563377d32a Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 9 Jul 2024 10:28:17 +0200 Subject: [PATCH 06/29] feat: readd drive by slug --- package-lock.json | 4 +- src/hooks/useClientErrorHandler.ts | 84 +++++++++++++++++++++++++++++- src/hooks/useSwitchboard.ts | 38 ++++++++++++++ 3 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 src/hooks/useSwitchboard.ts diff --git a/package-lock.json b/package-lock.json index 34b65cea..f7ef2f3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@powerhousedao/connect", - "version": "1.0.0-dev.36", + "version": "1.0.0-dev.38", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@powerhousedao/connect", - "version": "1.0.0-dev.36", + "version": "1.0.0-dev.38", "license": "AGPL-3.0-only", "dependencies": { "@powerhousedao/design-system": "1.0.0-alpha.147", diff --git a/src/hooks/useClientErrorHandler.ts b/src/hooks/useClientErrorHandler.ts index 2f49ad01..ebe900d2 100644 --- a/src/hooks/useClientErrorHandler.ts +++ b/src/hooks/useClientErrorHandler.ts @@ -5,6 +5,7 @@ import { } from 'document-model-libs/document-drive'; import { useCallback, useRef, useState } from 'react'; import { useDocumentDriveServer } from './useDocumentDriveServer'; +import { useSwitchboard } from './useSwitchboard'; export type ClientErrorHandler = { strandsErrorHandler: ( @@ -30,8 +31,16 @@ export const useClientErrorHandler = (): ClientErrorHandler => { const [pullResponderTriggerMap, setPullResponderTriggerMap] = useState< Map >(new Map()); - const { addTrigger, removeTrigger, registerNewPullResponderTrigger } = - useDocumentDriveServer(); + const { + addTrigger, + removeTrigger, + registerNewPullResponderTrigger, + renameDrive, + addRemoteDrive, + documentDrives, + } = useDocumentDriveServer(); + + const { getDriveIdBySlug } = useSwitchboard(); const pullResponderRegisterDelay = useRef>(new Map()); @@ -92,6 +101,66 @@ export const useClientErrorHandler = (): ClientErrorHandler => { ], ); + const handleDriveNotFound = useCallback( + async (driveId: string, trigger: Trigger, handlerCode: string) => { + setHandlingInProgress(state => [...state, handlerCode]); + try { + // get local drive by id + const drive = documentDrives.find( + drive => drive.state.global.id === driveId, + ); + if (!drive) return; + await removeTrigger(driveId, trigger.id); + + // rename the drive old name (old) + // check how many drives with the same name and old tag exist + const amountOfCopies = documentDrives.filter(d => { + return d.state.global.name.includes( + drive.state.global.name, + ); + }).length; + await renameDrive( + driveId, + drive.state.global.name + + ` (old${amountOfCopies > 0 ? ` ${amountOfCopies}` : ''})`, + ); + + if (trigger.data?.url && drive.state.global.slug) { + // TODO: fetch drive id by slug + + const newId = await getDriveIdBySlug( + trigger.data.url, + drive.state.global.slug, + ); + // generate new drive url + const urlParts = trigger.data.url.split('/'); + urlParts[urlParts.length - 1] = newId; + const newUrl = urlParts.join('/'); + + await addRemoteDrive(newUrl, { + availableOffline: true, + sharingType: 'private', + listeners: [], + triggers: [], + }); + } + } catch (e: any) { + console.error(e); + } finally { + setHandlingInProgress(state => + state.filter(code => code !== handlerCode), + ); + } + }, + [ + pullResponderTriggerMap, + removeTrigger, + addTrigger, + pullResponderRegisterDelay, + registerNewPullResponderTrigger, + ], + ); + const strandsErrorHandler: ClientErrorHandler['strandsErrorHandler'] = async (driveId, trigger, status, errorMessage) => { switch (status) { @@ -121,6 +190,17 @@ export const useClientErrorHandler = (): ClientErrorHandler => { break; } + + case 404: { + const handlerCode = `strands:${driveId}:${status}`; + if (handlingInProgress.includes(handlerCode)) return; + setTimeout( + () => + handleDriveNotFound(driveId, trigger, handlerCode), + 0, + ); + break; + } } }; diff --git a/src/hooks/useSwitchboard.ts b/src/hooks/useSwitchboard.ts new file mode 100644 index 00000000..7f424076 --- /dev/null +++ b/src/hooks/useSwitchboard.ts @@ -0,0 +1,38 @@ +export function useSwitchboard() { + return { + getDriveIdBySlug: async (driveUrl: string, slug: string) => { + if (!driveUrl) { + return; + } + + const urlParts = driveUrl.split('/'); + urlParts.pop(); // remove id + urlParts.pop(); // remove /d + urlParts.push('drives'); // add /drives + const drivesUrl = urlParts.join('/'); + const result = await fetch(drivesUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + query: ` + query getDriveIdBySlug($slug: String!) { + driveBySlug(slug: $slug) { + id + } + } + `, + variables: { + slug, + }, + }), + }); + + const data = (await result.json()) as { + data: { driveBySlug: { id: string } }; + }; + return data.data.driveBySlug.id; + }, + }; +} From 8d354d33b8cf63cf4d2b34800b8ff2a77bb79646 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 9 Jul 2024 10:51:06 +0200 Subject: [PATCH 07/29] fix: switchboard graphql query --- src/hooks/useSwitchboard.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/hooks/useSwitchboard.ts b/src/hooks/useSwitchboard.ts index 7f424076..f25b3c58 100644 --- a/src/hooks/useSwitchboard.ts +++ b/src/hooks/useSwitchboard.ts @@ -18,9 +18,7 @@ export function useSwitchboard() { body: JSON.stringify({ query: ` query getDriveIdBySlug($slug: String!) { - driveBySlug(slug: $slug) { - id - } + driveIdBySlug(slug: $slug) } `, variables: { @@ -30,9 +28,10 @@ export function useSwitchboard() { }); const data = (await result.json()) as { - data: { driveBySlug: { id: string } }; + data: { driveIdBySlug: string }; }; - return data.data.driveBySlug.id; + + return data.data.driveIdBySlug; }, }; } From fa29b9042e764cd58f96073f2967478372b289ce Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 9 Jul 2024 10:54:43 +0200 Subject: [PATCH 08/29] fix: set old drive private and new drive public --- src/hooks/useClientErrorHandler.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hooks/useClientErrorHandler.ts b/src/hooks/useClientErrorHandler.ts index ebe900d2..450c53c9 100644 --- a/src/hooks/useClientErrorHandler.ts +++ b/src/hooks/useClientErrorHandler.ts @@ -38,6 +38,7 @@ export const useClientErrorHandler = (): ClientErrorHandler => { renameDrive, addRemoteDrive, documentDrives, + setDriveSharingType, } = useDocumentDriveServer(); const { getDriveIdBySlug } = useSwitchboard(); @@ -125,6 +126,8 @@ export const useClientErrorHandler = (): ClientErrorHandler => { ` (old${amountOfCopies > 0 ? ` ${amountOfCopies}` : ''})`, ); + await setDriveSharingType(driveId, 'PRIVATE'); + if (trigger.data?.url && drive.state.global.slug) { // TODO: fetch drive id by slug @@ -139,7 +142,7 @@ export const useClientErrorHandler = (): ClientErrorHandler => { await addRemoteDrive(newUrl, { availableOffline: true, - sharingType: 'private', + sharingType: 'PUBLIC', listeners: [], triggers: [], }); From 2eef751cd27301549a7e10a2d202e13106463459 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 9 Jul 2024 11:18:54 +0200 Subject: [PATCH 09/29] chore: optimized drive not found handling --- src/hooks/useClientErrorHandler.ts | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/hooks/useClientErrorHandler.ts b/src/hooks/useClientErrorHandler.ts index 450c53c9..cf62c4e6 100644 --- a/src/hooks/useClientErrorHandler.ts +++ b/src/hooks/useClientErrorHandler.ts @@ -122,30 +122,29 @@ export const useClientErrorHandler = (): ClientErrorHandler => { }).length; await renameDrive( driveId, - drive.state.global.name + - ` (old${amountOfCopies > 0 ? ` ${amountOfCopies}` : ''})`, + drive.state.global.name + ` (${drive.state.global.id})`, ); await setDriveSharingType(driveId, 'PRIVATE'); if (trigger.data?.url && drive.state.global.slug) { - // TODO: fetch drive id by slug - const newId = await getDriveIdBySlug( trigger.data.url, drive.state.global.slug, ); - // generate new drive url - const urlParts = trigger.data.url.split('/'); - urlParts[urlParts.length - 1] = newId; - const newUrl = urlParts.join('/'); - - await addRemoteDrive(newUrl, { - availableOffline: true, - sharingType: 'PUBLIC', - listeners: [], - triggers: [], - }); + // if newId provided add new remote drive + if (newId) { + const urlParts = trigger.data.url.split('/'); + urlParts[urlParts.length - 1] = newId; + const newUrl = urlParts.join('/'); + + await addRemoteDrive(newUrl, { + availableOffline: true, + sharingType: 'PUBLIC', + listeners: [], + triggers: [], + }); + } } } catch (e: any) { console.error(e); From a517186e6c863d3c25ae7b748f88988f0fc4eae3 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 9 Jul 2024 11:21:32 +0200 Subject: [PATCH 10/29] chore: cleanup --- src/hooks/useClientErrorHandler.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/hooks/useClientErrorHandler.ts b/src/hooks/useClientErrorHandler.ts index cf62c4e6..0241897f 100644 --- a/src/hooks/useClientErrorHandler.ts +++ b/src/hooks/useClientErrorHandler.ts @@ -113,13 +113,6 @@ export const useClientErrorHandler = (): ClientErrorHandler => { if (!drive) return; await removeTrigger(driveId, trigger.id); - // rename the drive old name (old) - // check how many drives with the same name and old tag exist - const amountOfCopies = documentDrives.filter(d => { - return d.state.global.name.includes( - drive.state.global.name, - ); - }).length; await renameDrive( driveId, drive.state.global.name + ` (${drive.state.global.id})`, @@ -132,7 +125,6 @@ export const useClientErrorHandler = (): ClientErrorHandler => { trigger.data.url, drive.state.global.slug, ); - // if newId provided add new remote drive if (newId) { const urlParts = trigger.data.url.split('/'); urlParts[urlParts.length - 1] = newId; From a5efb04da6dcedf43a5f7d833bac8fd11d1f46be Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 9 Jul 2024 10:16:42 +0000 Subject: [PATCH 11/29] chore(release): set `package.json` to 1.0.0-dev.39 [skip ci] # [1.0.0-dev.39](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-dev.38...v1.0.0-dev.39) (2024-07-09) ### Bug Fixes * set old drive private and new drive public ([fa29b90](https://github.com/powerhouse-inc/document-model-electron/commit/fa29b9042e764cd58f96073f2967478372b289ce)) * switchboard graphql query ([8d354d3](https://github.com/powerhouse-inc/document-model-electron/commit/8d354d33b8cf63cf4d2b34800b8ff2a77bb79646)) ### Features * readd drive by slug ([631bcc3](https://github.com/powerhouse-inc/document-model-electron/commit/631bcc36fafaa9fe8502820d9ac872563377d32a)) --- CHANGELOG.md | 13 +++++++++++++ package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af40e770..fa1ba636 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# [1.0.0-dev.39](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-dev.38...v1.0.0-dev.39) (2024-07-09) + + +### Bug Fixes + +* set old drive private and new drive public ([fa29b90](https://github.com/powerhouse-inc/document-model-electron/commit/fa29b9042e764cd58f96073f2967478372b289ce)) +* switchboard graphql query ([8d354d3](https://github.com/powerhouse-inc/document-model-electron/commit/8d354d33b8cf63cf4d2b34800b8ff2a77bb79646)) + + +### Features + +* readd drive by slug ([631bcc3](https://github.com/powerhouse-inc/document-model-electron/commit/631bcc36fafaa9fe8502820d9ac872563377d32a)) + # [1.0.0-dev.38](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-dev.37...v1.0.0-dev.38) (2024-07-08) diff --git a/package.json b/package.json index 63a65630..e0b4e3bd 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@powerhousedao/connect", "productName": "Powerhouse-Connect", - "version": "1.0.0-dev.38", + "version": "1.0.0-dev.39", "description": "Powerhouse Connect", "main": ".vite/build/main.js", "license": "AGPL-3.0-only", From 0217983a79c959ad2c67b9cd901758dd83b5dbe9 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 9 Jul 2024 12:28:48 +0000 Subject: [PATCH 12/29] chore(release): set `package.json` to 1.0.0-dev.40 [skip ci] # [1.0.0-dev.40](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-dev.39...v1.0.0-dev.40) (2024-07-09) ### Bug Fixes * endpoints for connect ([7c81639](https://github.com/powerhouse-inc/document-model-electron/commit/7c81639f01764ee0703c0a0313305f7557994f06)) * semantic release ([b24fa8d](https://github.com/powerhouse-inc/document-model-electron/commit/b24fa8d03309c4f2f5d43372a34388dd0a168e59)) ### Features * added addpublicdrive util ([4dc536f](https://github.com/powerhouse-inc/document-model-electron/commit/4dc536f82216f47a8db46225ac1f6d6e1f9c7a23)) * added cypress CI config ([6418f6d](https://github.com/powerhouse-inc/document-model-electron/commit/6418f6d06b8f9d14012ab660a21f0b8b35af008a)) * added Cypress Cloud Config ([24deddb](https://github.com/powerhouse-inc/document-model-electron/commit/24deddb0518dc49e14538e29045e56eeab735b62)) * added cypress setup ([380db83](https://github.com/powerhouse-inc/document-model-electron/commit/380db83614f692230bbd11ebff63007599745f0d)) * added develop environment ([4ceabce](https://github.com/powerhouse-inc/document-model-electron/commit/4ceabce3c8e5d43488abda4a83d524b59da0c338)) * added develop to release cycle ([3e1058e](https://github.com/powerhouse-inc/document-model-electron/commit/3e1058eac31ac13d74aaed32418d6ac56ad4e3dd)) * added reload Connect toast ([37cb55e](https://github.com/powerhouse-inc/document-model-electron/commit/37cb55ecf4b746025de9c613d176a250505559c6)) * added version comparison ([866e979](https://github.com/powerhouse-inc/document-model-electron/commit/866e979684d884528cb06568ee92d02ec1253308)) * avoid recreate fileOptions and clickOptionsHandler for each file node ([08557e9](https://github.com/powerhouse-inc/document-model-electron/commit/08557e983c663e58a0bb68534b11df579f9be045)) * avoid recreate folderOptions and clickFolderOptionsHandler for each folder node ([efa90d2](https://github.com/powerhouse-inc/document-model-electron/commit/efa90d2664c025247ae6636a2c06706b12b1ad96)) * bump libs ([e11a238](https://github.com/powerhouse-inc/document-model-electron/commit/e11a23886304d971c1bf8ae7db92cbbe63c5d185)) * bump libs ([4e0863a](https://github.com/powerhouse-inc/document-model-electron/commit/4e0863af39e148053154fdcd2cb5ca5f3c801c6b)) * bump libs ([87d0d1a](https://github.com/powerhouse-inc/document-model-electron/commit/87d0d1af3997d258065bcdf91f7eba74e1e845ae)) * enabled sync icons for folders and files ([3e0451e](https://github.com/powerhouse-inc/document-model-electron/commit/3e0451e923151a497894c2b282a3324c11be2867)) * moved isAllowedToCreateDocuments to folderView ([8ef573b](https://github.com/powerhouse-inc/document-model-electron/commit/8ef573bafb079ebf5e32e6611c25d85225fe6190)) * re-use decodedDriveID ([bb11105](https://github.com/powerhouse-inc/document-model-electron/commit/bb111052681fd6fb73671ad026b16a22c03ec139)) * removed debug code ([5f0c930](https://github.com/powerhouse-inc/document-model-electron/commit/5f0c930c3c2fb19dfbd46a957fda4655f8549a72)) * update query ([2e5d77f](https://github.com/powerhouse-inc/document-model-electron/commit/2e5d77fdfd0cab9794563ef70e88954c9b99c73f)) * updated design-system alpha 119 ([b337897](https://github.com/powerhouse-inc/document-model-electron/commit/b3378976dd6f75b11b028734ad0e4dee09918b33)) * updated document drive ([39f3218](https://github.com/powerhouse-inc/document-model-electron/commit/39f3218c6919b4fb72a5641733da60b8eeac69c2)) * updated document-drive ([2a08adb](https://github.com/powerhouse-inc/document-model-electron/commit/2a08adb7fdd6a46af4c8d8ff31c946e043dbb016)) * updated libs ([adbadc1](https://github.com/powerhouse-inc/document-model-electron/commit/adbadc1d0b826acfc7e112d07d1c478496ac93cb)) * updated release script ([d5b4fd6](https://github.com/powerhouse-inc/document-model-electron/commit/d5b4fd60008696328dea4bf69b382ed8e1be527e)) * use memoized version of FileItem component ([8b0314b](https://github.com/powerhouse-inc/document-model-electron/commit/8b0314ba7ef8d538dc680d4a036b9c010a039273)) ### Performance Improvements * decode id only one when getting readable item path ([9d0b5ad](https://github.com/powerhouse-inc/document-model-electron/commit/9d0b5ad785a7a7e1c174f3190f87c6ee26f30251)) * implemented scalable way to compare drive state ([bb5fecb](https://github.com/powerhouse-inc/document-model-electron/commit/bb5fecb8e31385abc5697a4635c2dfb0823ba853)) --- CHANGELOG.md | 42 ++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51dd2277..dad7b2a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,45 @@ +# [1.0.0-dev.40](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-dev.39...v1.0.0-dev.40) (2024-07-09) + + +### Bug Fixes + +* endpoints for connect ([7c81639](https://github.com/powerhouse-inc/document-model-electron/commit/7c81639f01764ee0703c0a0313305f7557994f06)) +* semantic release ([b24fa8d](https://github.com/powerhouse-inc/document-model-electron/commit/b24fa8d03309c4f2f5d43372a34388dd0a168e59)) + + +### Features + +* added addpublicdrive util ([4dc536f](https://github.com/powerhouse-inc/document-model-electron/commit/4dc536f82216f47a8db46225ac1f6d6e1f9c7a23)) +* added cypress CI config ([6418f6d](https://github.com/powerhouse-inc/document-model-electron/commit/6418f6d06b8f9d14012ab660a21f0b8b35af008a)) +* added Cypress Cloud Config ([24deddb](https://github.com/powerhouse-inc/document-model-electron/commit/24deddb0518dc49e14538e29045e56eeab735b62)) +* added cypress setup ([380db83](https://github.com/powerhouse-inc/document-model-electron/commit/380db83614f692230bbd11ebff63007599745f0d)) +* added develop environment ([4ceabce](https://github.com/powerhouse-inc/document-model-electron/commit/4ceabce3c8e5d43488abda4a83d524b59da0c338)) +* added develop to release cycle ([3e1058e](https://github.com/powerhouse-inc/document-model-electron/commit/3e1058eac31ac13d74aaed32418d6ac56ad4e3dd)) +* added reload Connect toast ([37cb55e](https://github.com/powerhouse-inc/document-model-electron/commit/37cb55ecf4b746025de9c613d176a250505559c6)) +* added version comparison ([866e979](https://github.com/powerhouse-inc/document-model-electron/commit/866e979684d884528cb06568ee92d02ec1253308)) +* avoid recreate fileOptions and clickOptionsHandler for each file node ([08557e9](https://github.com/powerhouse-inc/document-model-electron/commit/08557e983c663e58a0bb68534b11df579f9be045)) +* avoid recreate folderOptions and clickFolderOptionsHandler for each folder node ([efa90d2](https://github.com/powerhouse-inc/document-model-electron/commit/efa90d2664c025247ae6636a2c06706b12b1ad96)) +* bump libs ([e11a238](https://github.com/powerhouse-inc/document-model-electron/commit/e11a23886304d971c1bf8ae7db92cbbe63c5d185)) +* bump libs ([4e0863a](https://github.com/powerhouse-inc/document-model-electron/commit/4e0863af39e148053154fdcd2cb5ca5f3c801c6b)) +* bump libs ([87d0d1a](https://github.com/powerhouse-inc/document-model-electron/commit/87d0d1af3997d258065bcdf91f7eba74e1e845ae)) +* enabled sync icons for folders and files ([3e0451e](https://github.com/powerhouse-inc/document-model-electron/commit/3e0451e923151a497894c2b282a3324c11be2867)) +* moved isAllowedToCreateDocuments to folderView ([8ef573b](https://github.com/powerhouse-inc/document-model-electron/commit/8ef573bafb079ebf5e32e6611c25d85225fe6190)) +* re-use decodedDriveID ([bb11105](https://github.com/powerhouse-inc/document-model-electron/commit/bb111052681fd6fb73671ad026b16a22c03ec139)) +* removed debug code ([5f0c930](https://github.com/powerhouse-inc/document-model-electron/commit/5f0c930c3c2fb19dfbd46a957fda4655f8549a72)) +* update query ([2e5d77f](https://github.com/powerhouse-inc/document-model-electron/commit/2e5d77fdfd0cab9794563ef70e88954c9b99c73f)) +* updated design-system alpha 119 ([b337897](https://github.com/powerhouse-inc/document-model-electron/commit/b3378976dd6f75b11b028734ad0e4dee09918b33)) +* updated document drive ([39f3218](https://github.com/powerhouse-inc/document-model-electron/commit/39f3218c6919b4fb72a5641733da60b8eeac69c2)) +* updated document-drive ([2a08adb](https://github.com/powerhouse-inc/document-model-electron/commit/2a08adb7fdd6a46af4c8d8ff31c946e043dbb016)) +* updated libs ([adbadc1](https://github.com/powerhouse-inc/document-model-electron/commit/adbadc1d0b826acfc7e112d07d1c478496ac93cb)) +* updated release script ([d5b4fd6](https://github.com/powerhouse-inc/document-model-electron/commit/d5b4fd60008696328dea4bf69b382ed8e1be527e)) +* use memoized version of FileItem component ([8b0314b](https://github.com/powerhouse-inc/document-model-electron/commit/8b0314ba7ef8d538dc680d4a036b9c010a039273)) + + +### Performance Improvements + +* decode id only one when getting readable item path ([9d0b5ad](https://github.com/powerhouse-inc/document-model-electron/commit/9d0b5ad785a7a7e1c174f3190f87c6ee26f30251)) +* implemented scalable way to compare drive state ([bb5fecb](https://github.com/powerhouse-inc/document-model-electron/commit/bb5fecb8e31385abc5697a4635c2dfb0823ba853)) + # [1.0.0-dev.39](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-dev.38...v1.0.0-dev.39) (2024-07-09) diff --git a/package.json b/package.json index e0b4e3bd..ea370b38 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@powerhousedao/connect", "productName": "Powerhouse-Connect", - "version": "1.0.0-dev.39", + "version": "1.0.0-dev.40", "description": "Powerhouse Connect", "main": ".vite/build/main.js", "license": "AGPL-3.0-only", From 2fee1295ebbf3a025ae34651efa0c190c8abe39e Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 9 Jul 2024 12:44:29 +0000 Subject: [PATCH 13/29] chore(release): set `package.json` to 1.0.0-dev.41 [skip ci] # [1.0.0-dev.41](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-dev.40...v1.0.0-dev.41) (2024-07-09) ### Features * reload default drives when config has been updated ([edd9bfc](https://github.com/powerhouse-inc/document-model-electron/commit/edd9bfc1f1914c13855343d77b6fc8029df6f737)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dad7b2a7..b575fcb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [1.0.0-dev.41](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-dev.40...v1.0.0-dev.41) (2024-07-09) + + +### Features + +* reload default drives when config has been updated ([edd9bfc](https://github.com/powerhouse-inc/document-model-electron/commit/edd9bfc1f1914c13855343d77b6fc8029df6f737)) + # [1.0.0-dev.40](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-dev.39...v1.0.0-dev.40) (2024-07-09) diff --git a/package.json b/package.json index ea370b38..3a242cbd 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@powerhousedao/connect", "productName": "Powerhouse-Connect", - "version": "1.0.0-dev.40", + "version": "1.0.0-dev.41", "description": "Powerhouse Connect", "main": ".vite/build/main.js", "license": "AGPL-3.0-only", From c88989b3b29f501089234dcfc3a03ae94cc6d009 Mon Sep 17 00:00:00 2001 From: Guillermo Puente Date: Tue, 9 Jul 2024 16:29:25 -0400 Subject: [PATCH 14/29] feat: added debug tools modal --- public/settings.png | Bin 0 -> 17608 bytes .../modal/modals/DebugSettingsModal.tsx | 246 ++++++++++++++++++ src/components/modal/modals/index.ts | 2 + src/components/sidebar.tsx | 10 + src/hooks/useClientErrorHandler.ts | 6 + 5 files changed, 264 insertions(+) create mode 100644 public/settings.png create mode 100644 src/components/modal/modals/DebugSettingsModal.tsx diff --git a/public/settings.png b/public/settings.png new file mode 100644 index 0000000000000000000000000000000000000000..475761088bb1a3c935cd36284e25a52a02ccd3fb GIT binary patch literal 17608 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 void; +} + +type ComboboxOption = { + label: string; + value: string; +}; + +export const DebugSettingsModal: React.FC = props => { + const { open, onClose } = props; + const autoRegisterPullResponder = + localStorage.getItem('AUTO_REGISTER_PULL_RESPONDER') !== 'false'; + + console.log('autoRegisterPullResponder', autoRegisterPullResponder); + + const [selectedDrive, setSelectedDrive] = useState(); + const [selectedDriveTrigger, setSelectedDriveTrigger] = + useState(null); + const [driveUrl, setDriveUrl] = useState(''); + const [autoRegister, setAutoRegister] = useState({ + label: autoRegisterPullResponder ? 'Enabled' : 'Disabled', + value: autoRegisterPullResponder ? 'true' : 'false', + }); + const { + documentDrives, + removeTrigger, + addTrigger, + registerNewPullResponderTrigger, + } = useDocumentDriveServer(); + + console.log('documentDrives', documentDrives); + console.log('selectedDrive', selectedDrive); + + const driveTriggers = + documentDrives.find(drive => drive.state.global.id === selectedDrive) + ?.state.local.triggers || []; + + const isEmptyURL = driveUrl === ''; + const disableUrlButtons = !selectedDrive || isEmptyURL; + + const removeTriggerHandler = async () => { + if (!selectedDriveTrigger || !selectedDrive) return; + + await removeTrigger(selectedDrive, selectedDriveTrigger.value); + setSelectedDriveTrigger(null); + }; + + const addTriggerHandler = async (invalid = false) => { + if (!driveUrl || driveUrl === '' || !selectedDrive) return; + + if (!invalid) { + const pullResponderTrigger = await registerNewPullResponderTrigger( + selectedDrive, + driveUrl, + { pullInterval: 3000 }, + ); + await addTrigger(selectedDrive, pullResponderTrigger); + setDriveUrl(''); + + return; + } + + await addTrigger(selectedDrive, { + id: `invalid-trigger-${uuid()}`, + type: 'PullResponder', + data: { + interval: '3000', + listenerId: `ivalid-listener-${uuid()}`, + url: driveUrl, + }, + }); + setDriveUrl(''); + }; + + const handleDisableAutoResiterPullResponder = ( + selectedOption: ComboboxOption, + ) => { + setAutoRegister(selectedOption); + localStorage.setItem( + 'AUTO_REGISTER_PULL_RESPONDER', + selectedOption.value, + ); + }; + + return ( + { + if (!status) return onClose(); + }} + contentProps={{ + className: 'rounded-2xl', + }} + > +
+
+
Debug Tools
+ +
+ +
+ + Drive Tools: +
+ +
+ + { + if ( + !value || + !(typeof value === 'object') || + !('value' in value) + ) { + setSelectedDrive(undefined); + setSelectedDriveTrigger(null); + return; + } + + setSelectedDrive(value.value as string); + setSelectedDriveTrigger(null); + }} + options={documentDrives.map(drive => ({ + label: drive.state.global.name, + value: drive.state.global.id, + }))} + /> +
+ +
+
+ + { + handleDisableAutoResiterPullResponder( + value as ComboboxOption, + ); + }} + value={autoRegister} + options={[ + { label: 'Enabled', value: 'true' }, + { label: 'Disabled', value: 'false' }, + ]} + /> +
+
+ +
+
+ + { + setSelectedDriveTrigger( + value as ComboboxOption, + ); + }} + value={selectedDriveTrigger} + options={driveTriggers.map(trigger => ({ + label: `${trigger.id} - ${trigger.type}`, + value: trigger.id, + }))} + /> +
+
+ +
+
+ +
+
+ + + URL: +
+ } + value={driveUrl} + onChange={element => + setDriveUrl(element.target.value) + } + /> +
+
+ + +
+
+ +
+ ); +}; diff --git a/src/components/modal/modals/index.ts b/src/components/modal/modals/index.ts index a1ccdff7..1143c5c8 100644 --- a/src/components/modal/modals/index.ts +++ b/src/components/modal/modals/index.ts @@ -1,5 +1,6 @@ import { ConfirmationModal } from './ConfirmationModal'; import { CreateDocumentModal } from './CreateDocumentModal'; +import { DebugSettingsModal } from './DebugSettingsModal'; import { DeleteDriveModal } from './DeleteDriveModal'; import { DeleteItemModal } from './DeleteItemModal'; import { SettingsModal } from './SettingsModal'; @@ -12,6 +13,7 @@ export const modals = { settingsModal: SettingsModal, confirmationModal: ConfirmationModal, deleteDriveModal: DeleteDriveModal, + debugSettingsModal: DebugSettingsModal, } as const; export type Modals = typeof modals; diff --git a/src/components/sidebar.tsx b/src/components/sidebar.tsx index 723dfdf9..5d5f804e 100644 --- a/src/components/sidebar.tsx +++ b/src/components/sidebar.tsx @@ -23,6 +23,8 @@ export default function Sidebar() { const { user, openRenown, status } = useLogin(); + const connectDebug = localStorage.getItem('CONNECT_DEBUG') === 'true'; + function toggleCollapse() { setCollapsed(value => !value); } @@ -34,6 +36,14 @@ export default function Sidebar() { const headerContent = (
+ {connectDebug && ( + + )}
); diff --git a/src/hooks/useClientErrorHandler.ts b/src/hooks/useClientErrorHandler.ts index 0241897f..a177e783 100644 --- a/src/hooks/useClientErrorHandler.ts +++ b/src/hooks/useClientErrorHandler.ts @@ -165,6 +165,12 @@ export const useClientErrorHandler = (): ClientErrorHandler => { trigger.data?.listenerId, ) ) { + const autoRegisterPullResponder = + localStorage.getItem( + 'AUTO_REGISTER_PULL_RESPONDER', + ) !== 'false'; + + if (!autoRegisterPullResponder) return; const handlerCode = `strands:${driveId}:${status}`; if (handlingInProgress.includes(handlerCode)) return; From 539d8100a5e4a9f3f0adace01c58f7510f6c9cd3 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 11 Jul 2024 20:39:43 +0000 Subject: [PATCH 15/29] chore(release): set `package.json` to 1.0.0-dev.42 [skip ci] # [1.0.0-dev.42](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-dev.41...v1.0.0-dev.42) (2024-07-11) ### Features * added debug tools modal ([c88989b](https://github.com/powerhouse-inc/document-model-electron/commit/c88989b3b29f501089234dcfc3a03ae94cc6d009)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b575fcb2..6c2e78a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [1.0.0-dev.42](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-dev.41...v1.0.0-dev.42) (2024-07-11) + + +### Features + +* added debug tools modal ([c88989b](https://github.com/powerhouse-inc/document-model-electron/commit/c88989b3b29f501089234dcfc3a03ae94cc6d009)) + # [1.0.0-dev.41](https://github.com/powerhouse-inc/document-model-electron/compare/v1.0.0-dev.40...v1.0.0-dev.41) (2024-07-09) diff --git a/package.json b/package.json index 3a242cbd..f264833d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@powerhousedao/connect", "productName": "Powerhouse-Connect", - "version": "1.0.0-dev.41", + "version": "1.0.0-dev.42", "description": "Powerhouse Connect", "main": ".vite/build/main.js", "license": "AGPL-3.0-only", From fab24e14247b31a96df09ccc17e7a3d05b065194 Mon Sep 17 00:00:00 2001 From: Guillermo Puente Date: Mon, 15 Jul 2024 17:35:30 -0400 Subject: [PATCH 16/29] feat: added base e2e tests --- cypress.config.ts | 5 + cypress/e2e/navigation.cy.ts | 299 ++++++++++++++++++++++++++++++++++- cypress/e2e/utils/index.ts | 92 +++++++++++ src/components/ph-logo.tsx | 2 +- src/components/sidebar.tsx | 2 + src/pages/content.tsx | 6 +- 6 files changed, 396 insertions(+), 10 deletions(-) diff --git a/cypress.config.ts b/cypress.config.ts index 34544570..c6397b29 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -8,4 +8,9 @@ export default defineConfig({ // implement node event listeners here }, }, + env: { + TEST_PUBLIC_DRIVE: + 'https://apps.powerhouse.io/develop/powerhouse/switchboard/d/test', + TEST_PUBLIC_DRIVE_NAME: 'Test', + }, }); diff --git a/cypress/e2e/navigation.cy.ts b/cypress/e2e/navigation.cy.ts index 413c3499..94bd7ea1 100644 --- a/cypress/e2e/navigation.cy.ts +++ b/cypress/e2e/navigation.cy.ts @@ -1,8 +1,39 @@ /// -import { clearIndexDB, newFolder } from './utils'; +import { + addPublicDrive, + clearIndexDB, + clickContentViewItem, + clickContentViewItemOption, + clickSidebarItemOption, + connectDebugMenu, + getBreadcrumbItem, + newFolder, + selectSidebarItem, +} from './utils'; describe('Navigation', () => { + const maxRetries = 5; + + const validateGraphQLQuery = (retryCount = 0, expectedStatusCode = 200) => { + cy.wait('@graphqlQuery').then(interception => { + if (interception.response.statusCode === expectedStatusCode) { + assert.equal( + interception.response.statusCode, + expectedStatusCode, + `GraphQL query should return a ${expectedStatusCode} status`, + ); + } else if (retryCount < maxRetries) { + cy.log( + `Retry ${retryCount + 1}: GraphQL query failed with status ${interception.response.statusCode}`, + ); + validateGraphQLQuery(retryCount + 1, expectedStatusCode); + } else { + assert.fail(`GraphQL query failed after ${maxRetries} retries`); + } + }); + }; + before(async () => { cy.clearAllSessionStorage(); await clearIndexDB(); @@ -35,11 +66,263 @@ describe('Navigation', () => { cy.contains('Close').click(); }); - // it.only('should add public drive', () => { - // addPublicDrive( - // 'https://apps.powerhouse.io/powerhouse/switchboard/d/powerhouse', - // ); - // cy.contains('article', 'Powerhouse').should('be.visible'); - // selectSidebarItem('Powerhouse'); - // }); + it('should add public drive', () => { + const publicDriveUrl = Cypress.env('TEST_PUBLIC_DRIVE') as string; + const publicDriveName = Cypress.env('TEST_PUBLIC_DRIVE_NAME') as string; + + addPublicDrive(publicDriveUrl); + cy.contains('article', publicDriveName).should('be.visible'); + selectSidebarItem(publicDriveName); + }); + + it('should create and delete a folder inside test drive', () => { + const publicDriveName = Cypress.env('TEST_PUBLIC_DRIVE_NAME') as string; + selectSidebarItem(publicDriveName); + newFolder(publicDriveName, 'test-folder'); + cy.contains('test-folder').should('exist'); + + clickSidebarItemOption('test-folder', 'delete'); + + cy.contains('button', 'Delete').click(); + cy.contains('test-folder').should('not.exist'); + }); + + it('should rename a folder inside test drive', () => { + const publicDriveName = Cypress.env('TEST_PUBLIC_DRIVE_NAME') as string; + selectSidebarItem(publicDriveName); + newFolder(publicDriveName, 'test-folder'); + clickSidebarItemOption('test-folder', 'rename'); + + cy.get('input[value="test-folder"]') + .clear() + .type('renamed-folder{enter}'); + cy.contains('renamed-folder').should('exist'); + clickSidebarItemOption('renamed-folder', 'delete'); + cy.contains('button', 'Delete').click(); + }); + + it('should duplicate a folder inside test drive', () => { + const publicDriveName = Cypress.env('TEST_PUBLIC_DRIVE_NAME') as string; + selectSidebarItem(publicDriveName); + newFolder(publicDriveName, 'test-folder'); + clickSidebarItemOption('test-folder', 'duplicate'); + + cy.contains('test-folder').should('exist'); + cy.contains('test-folder (copy) 1').should('exist'); + + clickSidebarItemOption('test-folder', 'delete'); + cy.contains('button', 'Delete').click(); + + clickSidebarItemOption('test-folder (copy) 1', 'delete'); + cy.contains('button', 'Delete').click(); + }); + + it('should create a document model inside test drive folder', () => { + const publicDriveName = Cypress.env('TEST_PUBLIC_DRIVE_NAME') as string; + selectSidebarItem(publicDriveName); + + newFolder(publicDriveName, 'test-folder'); + selectSidebarItem('test-folder'); + + cy.contains('DocumentModel').click(); + cy.get('input[placeholder="Document name"]') + .clear() + .type('test-document'); + cy.get('button').contains('Create').click(); + cy.get('textarea[placeholder="Document Model Name"]').type('draft1'); + + cy.contains('Global State Schema').click(); + cy.contains('Close').click(); + + cy.contains('draft1').should('exist'); + + clickSidebarItemOption('test-folder', 'delete'); + cy.contains('button', 'Delete').click(); + }); + + it('should navigate by clicking folder items in content view', () => { + const publicDriveName = Cypress.env('TEST_PUBLIC_DRIVE_NAME') as string; + selectSidebarItem(publicDriveName); + + newFolder(publicDriveName, 'test-folder'); + newFolder('test-folder', 'test-folder-2'); + newFolder('test-folder-2', 'test-folder-3'); + newFolder('test-folder-3', 'test-folder-4'); + + selectSidebarItem('test-folder'); + + clickContentViewItem('test-folder-2'); + clickContentViewItem('test-folder-3'); + clickContentViewItem('test-folder-4'); + + clickSidebarItemOption('test-folder', 'delete'); + cy.contains('button', 'Delete').click(); + }); + + it('should navigate using the breadcrumb', () => { + const publicDriveName = Cypress.env('TEST_PUBLIC_DRIVE_NAME') as string; + selectSidebarItem(publicDriveName); + + newFolder(publicDriveName, 'test-folder'); + newFolder('test-folder', 'test-folder-2'); + newFolder('test-folder-2', 'test-folder-3'); + newFolder('test-folder-3', 'test-folder-4'); + + selectSidebarItem('test-folder-4'); + + getBreadcrumbItem('test-folder-3').should('be.visible').click(); + getBreadcrumbItem('test-folder-4').should('not.exist'); + + getBreadcrumbItem('test-folder-2').should('be.visible').click(); + getBreadcrumbItem('test-folder-3').should('not.exist'); + + getBreadcrumbItem('test-folder').should('be.visible').click(); + getBreadcrumbItem('test-folder-2').should('not.exist'); + + getBreadcrumbItem(publicDriveName).should('be.visible').click(); + getBreadcrumbItem('test-folder').should('not.exist'); + + clickSidebarItemOption('test-folder', 'delete'); + cy.contains('button', 'Delete').click(); + }); + + it('should open switchboard from document link', () => { + const rwaDocumentCloseSelector = + '#document-editor-context > div > div.flex.items-center.justify-between > div.flex.justify-end.gap-x-2 > button.grid.size-8.place-items-center.rounded.border.border-gray-200.active\\:opacity-50'; + const rwaSwitchboardLinkSelector = + '#document-editor-context > div > div.flex.items-center.justify-between > div.flex.justify-end.gap-x-2 > button:nth-child(1)'; + const publicDriveName = Cypress.env('TEST_PUBLIC_DRIVE_NAME') as string; + selectSidebarItem(publicDriveName); + + newFolder(publicDriveName, 'test-folder'); + selectSidebarItem('test-folder'); + + cy.contains('RWA Portfolio').click(); + cy.get('input[placeholder="Document name"]') + .clear() + .type('rwa-document'); + cy.get('button').contains('Create').click(); + + cy.window().then(win => { + cy.stub(win, 'open').as('windowOpen'); + }); + + cy.get(rwaSwitchboardLinkSelector).click(); + + cy.get('@windowOpen').should('have.been.called'); + + cy.get(rwaDocumentCloseSelector).click(); + cy.contains('rwa-document').should('exist'); + + clickSidebarItemOption('test-folder', 'delete'); + cy.contains('button', 'Delete').click(); + }); + + it('should open switchboard from file item menu', () => { + const rwaDocumentCloseSelector = + '#document-editor-context > div > div.flex.items-center.justify-between > div.flex.justify-end.gap-x-2 > button.grid.size-8.place-items-center.rounded.border.border-gray-200.active\\:opacity-50'; + const publicDriveName = Cypress.env('TEST_PUBLIC_DRIVE_NAME') as string; + selectSidebarItem(publicDriveName); + + newFolder(publicDriveName, 'test-folder'); + selectSidebarItem('test-folder'); + + cy.contains('RWA Portfolio').click(); + cy.get('input[placeholder="Document name"]') + .clear() + .type('rwa-document'); + cy.get('button').contains('Create').click(); + cy.get(rwaDocumentCloseSelector).click(); + + cy.contains('rwa-document').should('exist'); + + cy.window().then(win => { + cy.stub(win, 'open').as('windowOpen'); + }); + + clickContentViewItemOption('rwa-document', 'switchboard-link'); + + cy.get('@windowOpen').should('have.been.called'); + + clickSidebarItemOption('test-folder', 'delete'); + cy.contains('button', 'Delete').click(); + }); + + it('should open powerhouse webpage', () => { + cy.window().then(win => { + cy.stub(win, 'open').as('windowOpen'); + }); + + cy.get('#ph-logo-link').should('be.visible').click(); + + cy.get('@windowOpen').should( + 'be.calledWith', + 'https://www.powerhouse.inc/', + '_blank', + ); + }); + + it('should collapse/expand sidebar', () => { + const sidebarCollapseSelector = + '#sidebar > div.no-scrollbar.flex-1.overflow-auto.text-gray-900.transition-shadow > div.flex-shrink-0.mb-4.flex.justify-between.gap-4.px-4.pt-11.collapsed\\:justify-center > button'; + + cy.get(sidebarCollapseSelector).click(); + cy.get('#sidebar').invoke('outerWidth').should('eq', 58); + + cy.get(sidebarCollapseSelector).click(); + cy.get('#sidebar').invoke('outerWidth').should('eq', 304); + }); + + it('should open settings', () => { + cy.contains('Settings').click(); + cy.get('div[role="dialog"]').should('be.visible'); + cy.contains('Cancel').click(); + cy.get('div[role="dialog"]').should('not.exist'); + }); + + it('should enable/disable connect debug mode', () => { + connectDebugMenu(true); + cy.get('#connect-debug-button').should('be.visible'); + + connectDebugMenu(false); + cy.get('#connect-debug-button').should('not.exist'); + }); + + it('should register a new pull responder trigger when it becomes invalid', () => { + const publicDriveName = Cypress.env('TEST_PUBLIC_DRIVE_NAME') as string; + const publicDriveUrl = Cypress.env('TEST_PUBLIC_DRIVE') as string; + + connectDebugMenu(true); + cy.get('#connect-debug-button').click(); + + cy.intercept('POST', publicDriveUrl, req => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (req.body.operationName === 'strands') { + req.alias = 'graphqlQuery'; + } + }); + + cy.get('#selectedDrive').click(); + cy.get('#selectedDrive').contains(publicDriveName).click(); + + cy.get('#autoRegisterPullResponder').click(); + cy.get('#autoRegisterPullResponder').contains('Disabled').click(); + + cy.get('#driveTrigger').click(); + cy.get('div[role="option"]').click(); + cy.contains('button', 'Remove Trigger').click(); + + cy.get('#driveUrl').clear().type(`${publicDriveUrl}{enter}`); + cy.contains('button', 'Add Invalid Trigger').click(); + + validateGraphQLQuery(0, 400); + + cy.get('#autoRegisterPullResponder').click(); + cy.get('div[role="option"]').contains('Enabled').click(); + + validateGraphQLQuery(0, 200); + + cy.get('#close-modal').click(); + connectDebugMenu(false); + }); }); diff --git a/cypress/e2e/utils/index.ts b/cypress/e2e/utils/index.ts index d9ad52ef..fa7104e4 100644 --- a/cypress/e2e/utils/index.ts +++ b/cypress/e2e/utils/index.ts @@ -30,6 +30,59 @@ export const clearIndexDB = async () => { } }; +type SidebarItemOption = 'duplicate' | 'new-folder' | 'delete' | 'rename'; +type ContentViewItemOption = + | 'duplicate' + | 'delete' + | 'rename' + | 'switchboard-link'; + +const getOptionName = (option: SidebarItemOption) => { + switch (option) { + case 'duplicate': + return 'Duplicate'; + case 'new-folder': + return 'New Folder'; + case 'delete': + return 'Delete'; + case 'rename': + return 'Rename'; + } +}; + +const getContentViewOptionName = (option: ContentViewItemOption) => { + switch (option) { + case 'duplicate': + return 'Duplicate'; + case 'delete': + return 'Delete'; + case 'rename': + return 'Rename'; + case 'switchboard-link': + return 'Switchboard Link'; + } +}; + +export const clickSidebarItemOption = ( + folderName: string, + option: SidebarItemOption, +) => { + cy.get('article') + .contains(folderName) + .then(el => { + hoverElement(el[0]); + }); + + cy.get('article') + .contains(folderName) + .closest('article') + .children('button') + .click(); + + const optionName = getOptionName(option); + cy.contains(optionName).click(); +}; + export const newFolder = (parent: string, folderName: string) => { cy.get('article') .contains(parent) @@ -70,3 +123,42 @@ export const addPublicDrive = (url: string) => { cy.get('button').contains('Add drive').should('not.be.disabled'); cy.get('button').contains('Add drive').click(); }; + +export const connectDebugMenu = (on = true) => { + cy.window().then(window => { + window.localStorage.setItem('CONNECT_DEBUG', on ? 'true' : 'false'); + }); + + cy.reload(); +}; + +export const clickContentViewItem = (title: string) => { + cy.get('#content-view').contains(title).should('be.visible').click(); +}; + +export const clickContentViewItemOption = ( + itemName: string, + option: ContentViewItemOption, +) => { + cy.get('#content-view') + .contains(itemName) + .parent() + .parent() + .next() + .children('svg') + .invoke('attr', 'style', 'display: inline-block; width: 24px') + .click(); + + const optionName = getContentViewOptionName(option); + cy.contains(optionName).click(); +}; + +export const getBreadcrumbItem = (title: string) => { + return cy + .get('#content-view') + .children() + .first() + .children() + .first() + .contains(title); +}; diff --git a/src/components/ph-logo.tsx b/src/components/ph-logo.tsx index 3b7c2633..67999764 100644 --- a/src/components/ph-logo.tsx +++ b/src/components/ph-logo.tsx @@ -3,7 +3,7 @@ import { openUrl } from 'src/utils/openUrl'; export const PHLogo = () => { return ( -
+