From fc79f27064c5f3c8961caea01b3c18931a8b2845 Mon Sep 17 00:00:00 2001 From: Korvin Szanto Date: Sat, 27 Jan 2024 14:48:12 -0800 Subject: [PATCH 01/16] Vue 3 and working storybook --- .babelrc | 3 - .../assets/concrete/images/countries/jp.png | Bin 0 -> 1213 bytes .../assets/concrete/images/countries/us.png | Bin 0 -> 1433 bytes .../concrete/images/icons/bedrock/sprites.svg | 0 .storybook/assets/concrete/preview.html | 3 + .storybook/assets/images/examplejpeg.jpeg | Bin 0 -> 45712 bytes .storybook/assets/mockServiceWorker.js | 303 + .storybook/assets/scss/theme/main.scss | 73 +- .storybook/main.js | 39 +- .storybook/preview-head.html | 9 - .storybook/preview.js | 42 + .../js/frontend/components/AvatarCropper.vue | 14 +- .../AddScheduledBoardElementButton.vue | 38 +- .../Action/ExternalLinkAction.vue | 6 - .../Announcement/Action/GuideAction.vue | 2 +- .../Announcement/Action/VideoAction.vue | 2 - .../cms/components/Announcement/Broadcast.vue | 2 +- .../Button/ExternalLinkButton.vue | 6 - .../components/Announcement/Header/Header.vue | 4 +- .../cms/components/Announcement/Item/Item.vue | 10 +- .../components/Announcement/Modal/Modal.vue | 6 +- .../Slide/CollectSiteInformationSlide.vue | 5 +- .../Announcement/Slide/FeatureSlide.vue | 7 +- .../Announcement/Slide/WelcomeSlide.vue | 5 +- .../cms/components/BoardInstanceRuleList.vue | 2 +- assets/cms/components/Breadcrumb.vue | 1 + .../cms/components/CompletedProcessList.vue | 10 +- assets/cms/components/Help/Modal.vue | 42 +- assets/cms/components/Icon.vue | 21 +- assets/cms/components/IconButton.vue | 41 +- .../cms/components/Image/ThumbnailEditor.vue | 4 +- assets/cms/components/Pagination.vue | 10 +- assets/cms/components/RunningProcessList.vue | 2 +- .../customizer/ColorPageCustomizerWidget.vue | 1 + .../FontFamilyPageCustomizerWidget.vue | 1 + .../customizer/ImagePageCustomizerWidget.vue | 4 +- .../TextTransformPageCustomizerWidget.vue | 2 +- .../components/customizer/ThemeCustomizer.vue | 18 +- .../customizer/TypePageCustomizerWidget.vue | 17 +- .../customizer/block/ToolbarSliderWidget.vue | 1 + .../customizer/flyout/FlyoutMenu.vue | 16 - assets/cms/components/express/Selector.vue | 4 +- .../cms/components/file-manager/Chooser.vue | 20 +- .../Chooser/ExternalFileProvider.vue | 10 +- .../file-manager/Chooser/FileManager.vue | 4 +- .../file-manager/Chooser/FileSets.vue | 4 +- .../file-manager/Chooser/FileUpload.vue | 4 +- .../components/file-manager/Chooser/Files.vue | 2 +- .../file-manager/Chooser/FolderBookmark.vue | 5 +- .../file-manager/Chooser/Header.vue | 2 +- .../file-manager/Chooser/RecentUploads.vue | 4 +- .../file-manager/Chooser/SavedSearch.vue | 4 +- .../file-manager/Chooser/Search.vue | 6 +- .../cms/components/file-manager/Uploader.vue | 4 +- .../Uploader/UploadFromComputer.vue | 1 + .../components/form/ConcreteAjaxSelect.vue | 4 + .../form/ConcreteExpressEntrySelect.vue | 3 +- .../form/ConcreteFileDirectoryInput.vue | 3 + .../components/form/ConcreteLocaleSelect.vue | 2 + .../components/form/ConcreteOptionSelect.vue | 2 +- .../components/form/ConcretePageSelect.vue | 3 +- assets/cms/components/form/ConcreteSelect.vue | 3 +- .../form/ConcreteThemeColorInput.vue | 1 + .../components/form/ConcreteUserSelect.vue | 2 +- assets/cms/components/form/IconSelector.vue | 18 +- assets/cms/components/form/PasswordInput.vue | 6 + assets/cms/components/form/Toggle.vue | 66 +- assets/cms/components/gallery/GalleryEdit.vue | 30 +- assets/cms/components/gallery/ImageCell.vue | 58 +- assets/cms/components/gallery/ImageDetail.vue | 2 +- assets/cms/components/index.js | 88 +- assets/cms/components/menu/ContextMenu.vue | 10 +- assets/cms/components/menu/MenuButton.vue | 21 +- assets/cms/components/menu/MenuDivider.vue | 2 +- assets/cms/components/menu/MenuItem.vue | 22 +- .../components/page/Chooser/ChooserSearch.vue | 9 +- assets/cms/components/page/PageList.vue | 3 +- assets/cms/components/user/Chooser.vue | 2 +- assets/cms/components/user/Chooser/Search.vue | 4 +- assets/cms/js/base.js | 4 +- components.txt | 0 package-lock.json | 32997 ++++++---------- package.json | 50 +- stories/account/AvatarCropper.stories.js | 54 + stories/announcement/Broadcast.stories.js | 19 + .../action/ExternalLinkAction.stories.js | 12 + .../action/GuideAction.stories.js | 13 + .../action/VideoAction.stories.js | 14 + .../button/ExternalLinkButton.stories.js | 13 + stories/announcement/header/Header.stories.js | 17 + stories/announcement/item/Item.stories.js | 38 + stories/announcement/modal/Modal.stories.js | 48 + .../CollectSiteInformationSlide.stories.js | 16 + .../slide/FeatureSlide.stories.js | 42 + .../slide/WelcomeSlide.stories.js | 18 + stories/avatar/cropper.stories.js | 17 - stories/basics/Breadcrumb.stories.js | 21 + stories/basics/RunningProcessList.stories.js | 41 + stories/basics/icon.stories.js | 45 +- stories/basics/iconButton.stories.js | 262 +- stories/basics/iconSelector.stories.js | 29 - .../AddScheduledBoardElementButton.stories.js | 32 + .../AddScheduledBoardElementModal.stories.js | 29 + stories/board/Board.stories.js | 16 + stories/board/BoardInstanceRule.stories.js | 18 + .../board/BoardInstanceRuleList.stories.js | 17 + stories/board/BoardSlot.stories.js | 27 + stories/cms/CompletedProcessList.stories.js | 39 + stories/cms/Pagination.stories.js | 34 + .../ColorPageCustomizerWidget.stories.js | 21 + stories/customizer/FlyoutMenu.stories.js | 17 + .../FontFamilyPageCustomizerWidget.stories.js | 26 + .../FontStylePageCustomizerWidget.stories.js | 21 + .../FontWeightPageCustomizerWidget.stories.js | 19 + .../ImagePageCustomizerWidget.stories.js | 26 + .../SizePageCustomizerWidget.stories.js | 22 + ...tDecorationPageCustomizerWidget.stories.js | 21 + ...xtTransformPageCustomizerWidget.stories.js | 18 + stories/customizer/ThemeCustomizer.stories.js | 29 + .../ThemeCustomizerPreview.stories.js | 14 + .../ToolbarSectionWidget.stories.js | 18 + .../customizer/ToolbarSliderWidget.stories.js | 20 + .../TypePageCustomizerWidget.stories.js | 22 + stories/express/Selector.stories.js | 20 + .../file-manager/chooser/Chooser.stories.js | 18 + .../chooser/ExternalFileProvider.stories.js | 20 + .../chooser/FileManager.stories.js | 24 + .../file-manager/chooser/FileSets.stories.js | 23 + .../chooser/FileUpload.stories.js | 29 + stories/file-manager/chooser/Files.stories.js | 23 + .../chooser/FolderBookmark.stories.js | 24 + .../file-manager/chooser/Header.stories.js | 22 + .../chooser/RecentUploads.stories.js | 16 + .../chooser/SavedSearch.stories.js | 22 + .../file-manager/chooser/Search.stories.js | 12 + .../uploader/UploadFromComputer.scss | 3 + .../uploader/UploadFromComputer.stories.js | 26 + .../file-manager/uploader/Uploader.stories.js | 28 + stories/forms/ConcreteAjaxSelect.stories.js | 38 + .../ConcreteEventOccurrenceInput.stories.js | 16 + .../ConcreteExpressEntryInput.stories.js | 13 + .../ConcreteExpressEntrySelect.stories.js | 41 + .../ConcreteFileDirectoryInput.stories.js | 36 + stories/forms/ConcreteFileInput.stories.js | 12 + stories/forms/ConcreteGroupInput.stories.js | 45 + stories/forms/ConcreteLocaleSelect.stories.js | 23 + stories/forms/ConcreteOptionSelect.stories.js | 14 + stories/forms/ConcretePageInput.stories.js | 13 + stories/forms/ConcretePageSelect.stories.js | 50 + stories/forms/ConcreteSelect.stories.js | 49 + stories/forms/ConcreteUserInput.stories.js | 10 + stories/forms/ConcreteUserSelect.stories.js | 16 + stories/forms/IconSelector.stories.js | 58 + stories/forms/PasswordInput.stories.js | 15 + .../forms/concreteThemeColorInput.stories.js | 35 + stories/forms/toggle.stories.js | 57 +- stories/gallery/galleryEdit.stories.js | 6 +- stories/gallery/imageCell.stories.js | 19 +- stories/gallery/imageDetail.stories.js | 11 +- stories/groups/Chooser.stories.js | 35 + stories/help/Modal.stories.js | 48 + stories/image/ThumbnailEditor.scss | 2 + stories/image/ThumbnailEditor.stories.js | 26 + stories/menu/ContextMenu.stories.js | 34 + stories/menu/MenuButton.stories.js | 56 + stories/menu/MenuDivider.stories.js | 23 + stories/menu/MenuItem.stories.js | 28 + stories/menu/menu.stories.js | 104 - stories/page/ChooserSearch.stories.js | 14 + stories/page/Fixtures.js | 29 + stories/page/PageList.stories.js | 14 + .../ConcreteToolbarSiteList.stories.js | 23 + stories/user/Chooser.stories.js | 15 + stories/user/chooser/Search.stories.js | 11 + stories/user/chooser/Users.stories.js | 13 + stories/user/main.js | 18 + webpack.mix.js | 53 - 177 files changed, 15761 insertions(+), 21158 deletions(-) delete mode 100644 .babelrc create mode 100644 .storybook/assets/concrete/images/countries/jp.png create mode 100644 .storybook/assets/concrete/images/countries/us.png rename .storybook/{public => assets}/concrete/images/icons/bedrock/sprites.svg (100%) create mode 100644 .storybook/assets/concrete/preview.html create mode 100644 .storybook/assets/images/examplejpeg.jpeg create mode 100644 .storybook/assets/mockServiceWorker.js delete mode 100644 .storybook/preview-head.html create mode 100644 components.txt create mode 100644 stories/account/AvatarCropper.stories.js create mode 100644 stories/announcement/Broadcast.stories.js create mode 100644 stories/announcement/action/ExternalLinkAction.stories.js create mode 100644 stories/announcement/action/GuideAction.stories.js create mode 100644 stories/announcement/action/VideoAction.stories.js create mode 100644 stories/announcement/button/ExternalLinkButton.stories.js create mode 100644 stories/announcement/header/Header.stories.js create mode 100644 stories/announcement/item/Item.stories.js create mode 100644 stories/announcement/modal/Modal.stories.js create mode 100644 stories/announcement/slide/CollectSiteInformationSlide.stories.js create mode 100644 stories/announcement/slide/FeatureSlide.stories.js create mode 100644 stories/announcement/slide/WelcomeSlide.stories.js delete mode 100644 stories/avatar/cropper.stories.js create mode 100644 stories/basics/Breadcrumb.stories.js create mode 100644 stories/basics/RunningProcessList.stories.js delete mode 100644 stories/basics/iconSelector.stories.js create mode 100644 stories/board/AddScheduledBoardElementButton.stories.js create mode 100644 stories/board/AddScheduledBoardElementModal.stories.js create mode 100644 stories/board/Board.stories.js create mode 100644 stories/board/BoardInstanceRule.stories.js create mode 100644 stories/board/BoardInstanceRuleList.stories.js create mode 100644 stories/board/BoardSlot.stories.js create mode 100644 stories/cms/CompletedProcessList.stories.js create mode 100644 stories/cms/Pagination.stories.js create mode 100644 stories/customizer/ColorPageCustomizerWidget.stories.js create mode 100644 stories/customizer/FlyoutMenu.stories.js create mode 100644 stories/customizer/FontFamilyPageCustomizerWidget.stories.js create mode 100644 stories/customizer/FontStylePageCustomizerWidget.stories.js create mode 100644 stories/customizer/FontWeightPageCustomizerWidget.stories.js create mode 100644 stories/customizer/ImagePageCustomizerWidget.stories.js create mode 100644 stories/customizer/SizePageCustomizerWidget.stories.js create mode 100644 stories/customizer/TextDecorationPageCustomizerWidget.stories.js create mode 100644 stories/customizer/TextTransformPageCustomizerWidget.stories.js create mode 100644 stories/customizer/ThemeCustomizer.stories.js create mode 100644 stories/customizer/ThemeCustomizerPreview.stories.js create mode 100644 stories/customizer/ToolbarSectionWidget.stories.js create mode 100644 stories/customizer/ToolbarSliderWidget.stories.js create mode 100644 stories/customizer/TypePageCustomizerWidget.stories.js create mode 100644 stories/express/Selector.stories.js create mode 100644 stories/file-manager/chooser/Chooser.stories.js create mode 100644 stories/file-manager/chooser/ExternalFileProvider.stories.js create mode 100644 stories/file-manager/chooser/FileManager.stories.js create mode 100644 stories/file-manager/chooser/FileSets.stories.js create mode 100644 stories/file-manager/chooser/FileUpload.stories.js create mode 100644 stories/file-manager/chooser/Files.stories.js create mode 100644 stories/file-manager/chooser/FolderBookmark.stories.js create mode 100644 stories/file-manager/chooser/Header.stories.js create mode 100644 stories/file-manager/chooser/RecentUploads.stories.js create mode 100644 stories/file-manager/chooser/SavedSearch.stories.js create mode 100644 stories/file-manager/chooser/Search.stories.js create mode 100644 stories/file-manager/uploader/UploadFromComputer.scss create mode 100644 stories/file-manager/uploader/UploadFromComputer.stories.js create mode 100644 stories/file-manager/uploader/Uploader.stories.js create mode 100644 stories/forms/ConcreteAjaxSelect.stories.js create mode 100644 stories/forms/ConcreteEventOccurrenceInput.stories.js create mode 100644 stories/forms/ConcreteExpressEntryInput.stories.js create mode 100644 stories/forms/ConcreteExpressEntrySelect.stories.js create mode 100644 stories/forms/ConcreteFileDirectoryInput.stories.js create mode 100644 stories/forms/ConcreteFileInput.stories.js create mode 100644 stories/forms/ConcreteGroupInput.stories.js create mode 100644 stories/forms/ConcreteLocaleSelect.stories.js create mode 100644 stories/forms/ConcreteOptionSelect.stories.js create mode 100644 stories/forms/ConcretePageInput.stories.js create mode 100644 stories/forms/ConcretePageSelect.stories.js create mode 100644 stories/forms/ConcreteSelect.stories.js create mode 100644 stories/forms/ConcreteUserInput.stories.js create mode 100644 stories/forms/ConcreteUserSelect.stories.js create mode 100644 stories/forms/IconSelector.stories.js create mode 100644 stories/forms/PasswordInput.stories.js create mode 100644 stories/forms/concreteThemeColorInput.stories.js create mode 100644 stories/groups/Chooser.stories.js create mode 100644 stories/help/Modal.stories.js create mode 100644 stories/image/ThumbnailEditor.scss create mode 100644 stories/image/ThumbnailEditor.stories.js create mode 100644 stories/menu/ContextMenu.stories.js create mode 100644 stories/menu/MenuButton.stories.js create mode 100644 stories/menu/MenuDivider.stories.js create mode 100644 stories/menu/MenuItem.stories.js delete mode 100644 stories/menu/menu.stories.js create mode 100644 stories/page/ChooserSearch.stories.js create mode 100644 stories/page/Fixtures.js create mode 100644 stories/page/PageList.stories.js create mode 100644 stories/toolbar/ConcreteToolbarSiteList.stories.js create mode 100644 stories/user/Chooser.stories.js create mode 100644 stories/user/chooser/Search.stories.js create mode 100644 stories/user/chooser/Users.stories.js create mode 100644 stories/user/main.js delete mode 100644 webpack.mix.js diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 370e4140..00000000 --- a/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@vue/babel-preset-jsx"] -} diff --git a/.storybook/assets/concrete/images/countries/jp.png b/.storybook/assets/concrete/images/countries/jp.png new file mode 100644 index 0000000000000000000000000000000000000000..2d95f867ee8106a592004a1aad39d0e5a8e8262e GIT binary patch literal 1213 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%s|1+P|wiV z#N6CmN5ROz&_Lh7NZ-&%*U;R`*vQJjKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8EkR}&8R-I5=oVMzl_XZ^<`pZ$OmImpPAEg{v+u2}(t{7puX=A(aKG z`a!A1`K3k4z=%sz23b{L-^Aq1JP;qO z-q+X4Gq1QLF)umQ)5TT^Xo6m5W{Q=8iJOb7fs?s~shOdnp{s$VrHiABvx}jzlcl+Z zn~^z8uSMv>2~2MaLazl*y`ZF!TL84#CABECEH%ZgC_h&L>}9J=+-@<&X&zK> z3U0TU;nb@Sbc{YIVv!;mCIn19ASOK70y*%6pPC0u?M1+3z5Qs+8wLhOLr)jSkcwMJ zg01@w83@$&1ub3RXd)uhJc;>2z=a@%w{bjg%R0CNE^N5&(RgF(B^4o|t}UHYw?D3V zBk>~WjmBij%0I_GA4_%>a#lIu!1>vxUTfhht!(+f`?4-xU|FoO%KYm~6TP>yHuld_ z@tpiXQs>`GmU;URY+`s`T(I-Y0k4(2x<07>C}1eJ4#?i1p?XpB&ri1d_i~&1rd>Z` zHDTFES4H|RmYMQRE4sV^t+_cWqOkq#OZp(z5w|>j+iMg|HThoO3({{J_FP5p;( Z0)zCQlBKQ;(@Q`Fil?ie%Q~loCIC8pspkLy literal 0 HcmV?d00001 diff --git a/.storybook/assets/concrete/images/countries/us.png b/.storybook/assets/concrete/images/countries/us.png new file mode 100644 index 0000000000000000000000000000000000000000..e1ebe0062b6b4d17bf8ebda18dd32f8e12dc61df GIT binary patch literal 1433 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%s|1+P|wiV z#N6CmN5ROz&_Lh7NZ-&%*U;R`*vQJjKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8EkR}&8R-I5=oVMzl_XZ^<`pZ$OmImpPAEg{v+u2}(t{7puX=A(aKG z`a!A1`K3k4z=%sz23b{L-^Aq1JP;qO z-q+X4Gq1QLF)umQ)5TT^Xo6m5W{Q=Oi?fA`lc}SHshOdnp{s$VrHiABvx}jzlcl+Z zn~^z8uSMv>2~2MaLa!4}y`ZF!TL84#CABECEH%ZgC_h&L>}9J=+-|YJX&zK> z3U0Sp;?%1Tbc{YIVv!;mCIn19ASOK70y*%6pPC0u?M1+3-SBkA0tN;qUQZXtkcwMJ zg1s|@14V2v`%PG-A<`mt@xigR)`E_!xC37v>Q&I{hzLA5RYE}2#bEV1mt7N-B3v)H zit9xMT!>n#*EPRa#Caiyr|L6jqnUnb&wSIKRXkUndLviN&SH;o|7qLrcdCyobjJC~ zSJ^yUx_bUUUBy1ug%cbcYWpD#9zx&H9W7hx&SrisSvA08$5cwAEBa8gQ|{rk}VM|=UB z8Fn*TWH-D%WKqquQ=i+D_5IeYMFvIY37c;|IT+pbwQBC~ydNgUcDc8grADr~nzbfu zbKY(UM_*#9Szl@Zgcf zp{4mj2XAD*{dpnxsN3R$e!+T6YUI6CsQai=y~q8uv^X!; zOD|VeGB4cn#iML8PlLp%T^%8OyY<{1?2c`_7`T>asfp0O$G0+{gcTWl`YFoC|Gq6m zQ7lQNd+HtO%J18sSKgS+q!wq}zO(ohW6$H|7tF2MSMqPrc^m3HWk!Yg`8UrxBc3sB zTmP?R +Example preview + \ No newline at end of file diff --git a/.storybook/assets/images/examplejpeg.jpeg b/.storybook/assets/images/examplejpeg.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..c1813afecb328871eaae61c781adc16604217823 GIT binary patch literal 45712 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.noA$IA3nE|--LQO$CNkzN>Yv6f2ALF; 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 YB { + return client.id !== clientId + }) + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister() + } + + break + } + } +}) + +self.addEventListener('fetch', function (event) { + const { request } = event + const accept = request.headers.get('accept') || '' + + // Bypass server-sent events. + if (accept.includes('text/event-stream')) { + return + } + + // Bypass navigation requests. + if (request.mode === 'navigate') { + return + } + + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { + return + } + + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return + } + + // Generate unique request ID. + const requestId = Math.random().toString(16).slice(2) + + event.respondWith( + handleRequest(event, requestId).catch((error) => { + if (error.name === 'NetworkError') { + console.warn( + '[MSW] Successfully emulated a network error for the "%s %s" request.', + request.method, + request.url, + ) + return + } + + // At this point, any exception indicates an issue with the original request/response. + console.error( + `\ +[MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`, + request.method, + request.url, + `${error.name}: ${error.message}`, + ) + }), + ) +}) + +async function handleRequest(event, requestId) { + const client = await resolveMainClient(event) + const response = await getResponse(event, client, requestId) + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + ;(async function () { + const clonedResponse = response.clone() + sendToClient(client, { + type: 'RESPONSE', + payload: { + requestId, + type: clonedResponse.type, + ok: clonedResponse.ok, + status: clonedResponse.status, + statusText: clonedResponse.statusText, + body: + clonedResponse.body === null ? null : await clonedResponse.text(), + headers: Object.fromEntries(clonedResponse.headers.entries()), + redirected: clonedResponse.redirected, + }, + }) + })() + } + + return response +} + +// Resolve the main client for the given event. +// Client that issues a request doesn't necessarily equal the client +// that registered the worker. It's with the latter the worker should +// communicate with during the response resolving phase. +async function resolveMainClient(event) { + const client = await self.clients.get(event.clientId) + + if (client?.frameType === 'top-level') { + return client + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }) + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible' + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id) + }) +} + +async function getResponse(event, client, requestId) { + const { request } = event + const clonedRequest = request.clone() + + function passthrough() { + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const headers = Object.fromEntries(clonedRequest.headers.entries()) + + // Remove MSW-specific request headers so the bypassed requests + // comply with the server's CORS preflight check. + // Operate with the headers as an object because request "Headers" + // are immutable. + delete headers['x-msw-bypass'] + + return fetch(clonedRequest, { headers }) + } + + // Bypass mocking when the client is not active. + if (!client) { + return passthrough() + } + + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough() + } + + // Bypass requests with the explicit bypass header. + // Such requests can be issued by "ctx.fetch()". + if (request.headers.get('x-msw-bypass') === 'true') { + return passthrough() + } + + // Notify the client that a request has been intercepted. + const clientMessage = await sendToClient(client, { + type: 'REQUEST', + payload: { + id: requestId, + url: request.url, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + mode: request.mode, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: await request.text(), + bodyUsed: request.bodyUsed, + keepalive: request.keepalive, + }, + }) + + switch (clientMessage.type) { + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data) + } + + case 'MOCK_NOT_FOUND': { + return passthrough() + } + + case 'NETWORK_ERROR': { + const { name, message } = clientMessage.data + const networkError = new Error(message) + networkError.name = name + + // Rejecting a "respondWith" promise emulates a network error. + throw networkError + } + } + + return passthrough() +} + +function sendToClient(client, message) { + return new Promise((resolve, reject) => { + const channel = new MessageChannel() + + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error) + } + + resolve(event.data) + } + + client.postMessage(message, [channel.port2]) + }) +} + +function sleep(timeMs) { + return new Promise((resolve) => { + setTimeout(resolve, timeMs) + }) +} + +async function respondWithMock(response) { + await sleep(response.delay) + return new Response(response.body, response) +} diff --git a/.storybook/assets/scss/theme/main.scss b/.storybook/assets/scss/theme/main.scss index c59f29a3..fcbc1bea 100644 --- a/.storybook/assets/scss/theme/main.scss +++ b/.storybook/assets/scss/theme/main.scss @@ -1,71 +1,2 @@ -// 01. Bootstrap Functions go first. -@import "node_modules/bootstrap/scss/functions"; - -// 02. Bootstrap overrides, have to be done BEFORE bootstrap. -// @todo this is all busted up, update it for new bedrock. -//@import "../../../../assets/cms/scss/bootstrap-overrides"; - -// 03. Bootstrap Variables -@import "node_modules/bootstrap/scss/variables"; - -// 04. Theme variables, some of which can now be based on bootstrap variable/constants/ -@import "../../../../assets/cms/scss/variables"; - -// Import the bootstrap mixins, variables and functions -@import "node_modules/bootstrap/scss/mixins"; - -// Import the base classes like core utilities and variables -@import "node_modules/@fortawesome/fontawesome-free/scss/variables"; - -// Import the subset of Bootstrap that is required in the CMS entry point. -// Make sure to namespace it to .ccm-ui -// Reboot HTML body and reboot tags are basically the bootstrap reboot.scss file split into two parts. -// The html and body tags are combined into the reboot_html_body.scss file, and the rest of the tags are -// just copied into reboot_tags.scs -@import "../../../../assets/cms/scss/bootstrap/reboot"; -div.ccm-ui { - @import "../../../../assets/cms/scss/bootstrap/reboot-tags"; - - // Import the bootstrap components we want. Note: I'm including everything in the list, and commenting out - // things that are either a) already included, b) not applicable, c) not used in our in-page CMS sub-set. - //@import "functions"; - //@import "variables"; - //@import "mixins"; - //@import "root"; - //@import "reboot"; - @import "node_modules/bootstrap/scss/type"; - //@import "images"; - @import "node_modules/bootstrap/scss/code"; - @import "node_modules/bootstrap/scss/grid"; - @import "node_modules/bootstrap/scss/tables"; - @import "node_modules/bootstrap/scss/forms"; - @import "node_modules/bootstrap/scss/buttons"; - @import "node_modules/bootstrap/scss/transitions"; - @import "node_modules/bootstrap/scss/dropdown"; - @import "node_modules/bootstrap/scss/button-group"; - @import "node_modules/bootstrap/scss/input-group"; - @import "node_modules/bootstrap/scss/custom-forms"; - @import "node_modules/bootstrap/scss/nav"; - //@import "navbar"; - @import "node_modules/bootstrap/scss/card"; - @import "node_modules/bootstrap/scss/breadcrumb"; - @import "node_modules/bootstrap/scss/pagination"; - @import "node_modules/bootstrap/scss/badge"; - //@import "jumbotron"; - @import "node_modules/bootstrap/scss/alert"; - @import "node_modules/bootstrap/scss/progress"; - @import "node_modules/bootstrap/scss/media"; - @import "node_modules/bootstrap/scss/list-group"; - @import "node_modules/bootstrap/scss/close"; - @import "node_modules/bootstrap/scss/toasts"; - //@import "modal"; - @import "node_modules/bootstrap/scss/tooltip"; - @import "node_modules/bootstrap/scss/popover"; - //@import "carousel"; - //@import "spinners"; - @import "node_modules/bootstrap/scss/utilities"; - //@import "print"; -} - -// This is the actual public entry point to the cms.css on the front-end -@import "../../../../assets/cms/scss/base"; \ No newline at end of file +@import '../../../../assets/bedrock/scss/frontend'; +@import '../../../../assets/account/scss/frontend'; \ No newline at end of file diff --git a/.storybook/main.js b/.storybook/main.js index 6023208d..7529d959 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,19 +1,20 @@ -const path = require('path'); - -// Load in laravel mix -const custom = require('../node_modules/laravel-mix/setup/webpack.config.js') - -module.exports = { - stories: ['../stories/**/*.stories.[tj]s'], - webpackFinal: config => { - return { - ...config, - module: { - ...config.module, - rules: [ - ...custom.module.rules - ] - } - } - } -} \ No newline at end of file +/** @type { import('@storybook/vue3-vite').StorybookConfig } */ +export default { + stories: [ + "../stories/**/*.mdx", + "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)", + ], + addons: [ + "@storybook/addon-links", + "@storybook/addon-essentials", + "@storybook/addon-interactions", + ], + framework: { + name: "@storybook/vue3-vite", + options: {}, + }, + docs: { + autodocs: "tag", + }, + staticDirs: [{from: './assets', 'to': '/'}] +}; diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html deleted file mode 100644 index 431162a1..00000000 --- a/.storybook/preview-head.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/.storybook/preview.js b/.storybook/preview.js index 8826134c..6809887f 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,2 +1,44 @@ +import { initialize, mswLoader } from 'msw-storybook-addon'; import '@fortawesome/fontawesome-free/css/all.css' import './assets/scss/theme/main.scss' + +// Bootstrap +import * as bootstrap from 'bootstrap/dist/js/bootstrap.esm'; + +// JQuery +import jQuery from "jquery"; + +window.$ = window.jquery = window.jQuery = jQuery +window.bootstrap = bootstrap + +$.fn.modal = (...args) => new bootstrap.Modal(...args) + +// Initialize MSW +initialize({ + onUnhandledRequest({method, url}) { + if (url.pathname.startsWith('/ccm')) { + console.error(`Unhandled ${method} request to ${url}`) + } + } +}); + +/** @type { import('@storybook/vue3').Preview } */ +const preview = { + parameters: { + actions: { argTypesRegex: "^on[A-Z].*" }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + }, + loaders: [mswLoader], + decorators: [ + () => ({ + template: `
`, + }) + ] +} + +export default preview; diff --git a/assets/account/js/frontend/components/AvatarCropper.vue b/assets/account/js/frontend/components/AvatarCropper.vue index afa925b2..5bb9d3fd 100644 --- a/assets/account/js/frontend/components/AvatarCropper.vue +++ b/assets/account/js/frontend/components/AvatarCropper.vue @@ -27,7 +27,7 @@ {{ lang.saveInProgress }} - + - diff --git a/assets/cms/components/Announcement/Action/ExternalLinkAction.vue b/assets/cms/components/Announcement/Action/ExternalLinkAction.vue index 83833b60..b051271c 100644 --- a/assets/cms/components/Announcement/Action/ExternalLinkAction.vue +++ b/assets/cms/components/Announcement/Action/ExternalLinkAction.vue @@ -15,11 +15,5 @@ export default { required: true } }, - data: () => ({ - }), - methods: { - }, - mounted() { - } } diff --git a/assets/cms/components/Announcement/Action/GuideAction.vue b/assets/cms/components/Announcement/Action/GuideAction.vue index 49b95ab2..a6c914f3 100644 --- a/assets/cms/components/Announcement/Action/GuideAction.vue +++ b/assets/cms/components/Announcement/Action/GuideAction.vue @@ -1,6 +1,6 @@ diff --git a/assets/cms/components/Announcement/Header/Header.vue b/assets/cms/components/Announcement/Header/Header.vue index 89607823..154cb615 100644 --- a/assets/cms/components/Announcement/Header/Header.vue +++ b/assets/cms/components/Announcement/Header/Header.vue @@ -26,8 +26,6 @@ export default { type: String, required: true } - }, - data: () => ({ - }) + } } diff --git a/assets/cms/components/Announcement/Item/Item.vue b/assets/cms/components/Announcement/Item/Item.vue index 75c76817..a23f0da1 100644 --- a/assets/cms/components/Announcement/Item/Item.vue +++ b/assets/cms/components/Announcement/Item/Item.vue @@ -16,9 +16,9 @@ diff --git a/assets/cms/components/Announcement/Modal/Modal.vue b/assets/cms/components/Announcement/Modal/Modal.vue index 4a9933c1..b18f65aa 100644 --- a/assets/cms/components/Announcement/Modal/Modal.vue +++ b/assets/cms/components/Announcement/Modal/Modal.vue @@ -11,9 +11,9 @@ diff --git a/assets/cms/components/Icon.vue b/assets/cms/components/Icon.vue index 1f754268..9121a0e7 100644 --- a/assets/cms/components/Icon.vue +++ b/assets/cms/components/Icon.vue @@ -1,20 +1,19 @@ - diff --git a/assets/cms/components/RunningProcessList.vue b/assets/cms/components/RunningProcessList.vue index 267afff7..a0ede832 100644 --- a/assets/cms/components/RunningProcessList.vue +++ b/assets/cms/components/RunningProcessList.vue @@ -34,7 +34,7 @@ /* global CCM_DISPATCHER_FILENAME, CCM_SERVER_EVENTS_URL, CCM_SECURITY_TOKEN */ /* eslint-disable no-new */ /* eslint eqeqeq: 0 */ -import Icon from './Icon' +import Icon from './Icon.vue' export default { components: { Icon diff --git a/assets/cms/components/customizer/ColorPageCustomizerWidget.vue b/assets/cms/components/customizer/ColorPageCustomizerWidget.vue index fb939b1a..4d2166d9 100644 --- a/assets/cms/components/customizer/ColorPageCustomizerWidget.vue +++ b/assets/cms/components/customizer/ColorPageCustomizerWidget.vue @@ -12,6 +12,7 @@ export default { color: this.styleValue.value } }, + emits: ['update'], mounted() { var my = this const i18n = window.ccmi18n_styleCustomizer || null diff --git a/assets/cms/components/customizer/FontFamilyPageCustomizerWidget.vue b/assets/cms/components/customizer/FontFamilyPageCustomizerWidget.vue index 2a333a99..cc59a73d 100644 --- a/assets/cms/components/customizer/FontFamilyPageCustomizerWidget.vue +++ b/assets/cms/components/customizer/FontFamilyPageCustomizerWidget.vue @@ -15,6 +15,7 @@ /* globals TomSelect, WebFont */ export default { components: {}, + emits: ['update'], data() { return { selectedFont: this.styleValue.value.fontFamily diff --git a/assets/cms/components/customizer/ImagePageCustomizerWidget.vue b/assets/cms/components/customizer/ImagePageCustomizerWidget.vue index 62bbc49a..6be10e5f 100644 --- a/assets/cms/components/customizer/ImagePageCustomizerWidget.vue +++ b/assets/cms/components/customizer/ImagePageCustomizerWidget.vue @@ -14,8 +14,8 @@ diff --git a/assets/cms/components/express/Selector.vue b/assets/cms/components/express/Selector.vue index 06a8c2a1..b3522b86 100644 --- a/assets/cms/components/express/Selector.vue +++ b/assets/cms/components/express/Selector.vue @@ -80,8 +80,8 @@ diff --git a/assets/cms/components/form/PasswordInput.vue b/assets/cms/components/form/PasswordInput.vue index f6de3e3c..a466cfe5 100644 --- a/assets/cms/components/form/PasswordInput.vue +++ b/assets/cms/components/form/PasswordInput.vue @@ -66,6 +66,7 @@ export default { default: false } }, + emits: ['change'], computed: { inputType() { return this.passwordVisible ? 'text' : 'password' @@ -88,6 +89,11 @@ export default { ) } }, + watch: { + enteredPassword(v) { + this.$emit('change', v) + }, + }, mounted() { if (window.ccmi18n_passwordInput) { for (const key in this.i18n) { diff --git a/assets/cms/components/form/Toggle.vue b/assets/cms/components/form/Toggle.vue index 4031c9e1..cdb10473 100644 --- a/assets/cms/components/form/Toggle.vue +++ b/assets/cms/components/form/Toggle.vue @@ -1,15 +1,15 @@ -