diff --git a/README-CN.md b/README-CN.md index af6d108864..b71e4fb279 100644 --- a/README-CN.md +++ b/README-CN.md @@ -94,8 +94,9 @@ ILLA CLI 使您能够以超乎想象的速度部署 ILLA Builder。 [单击此 加入 ILLA 社区,分享您的想法、建议或问题,并与其他用户和贡献者交流。 加入微信群: +![IMG_6451](https://github.com/illacloud/illa-builder/assets/112603073/06b024f1-5aad-428a-9342-ee4396d20e92) + -![IMG_6103](https://github.com/illacloud/illa-builder/assets/112603073/a4eb22b9-f826-49df-b538-75599292370f) Discord与Github社区入口 diff --git a/apps/builder/package.json b/apps/builder/package.json index 113def6c3b..3f01324845 100644 --- a/apps/builder/package.json +++ b/apps/builder/package.json @@ -5,7 +5,7 @@ "private": true, "author": "ILLA Cloud ", "license": "Apache-2.0", - "version": "4.5.18", + "version": "4.7.0", "scripts": { "dev": "vite --strictPort --force", "build-cloud": "NODE_OPTIONS=--max-old-space-size=12288 vite build --mode cloud", diff --git a/apps/builder/src/page/App/components/Actions/ActionList/listWithNewButton.tsx b/apps/builder/src/page/App/components/Actions/ActionList/listWithNewButton.tsx index 23ce04a708..74e422e299 100644 --- a/apps/builder/src/page/App/components/Actions/ActionList/listWithNewButton.tsx +++ b/apps/builder/src/page/App/components/Actions/ActionList/listWithNewButton.tsx @@ -1,4 +1,4 @@ -import { getIconFromResourceType } from "@illa-public/icon" +import { UpgradeIcon, getIconFromResourceType } from "@illa-public/icon" import { ILLA_MIXPANEL_BUILDER_PAGE_NAME, ILLA_MIXPANEL_EVENT_TYPE, @@ -22,6 +22,9 @@ import { ActionGenerator, ResourceGeneratorProvider, } from "@illa-public/resource-generator" +import { useUpgradeModal } from "@illa-public/upgrade-modal" +import { isSubscribeForUseDrive } from "@illa-public/upgrade-modal/utils" +import { getCurrentTeamInfo } from "@illa-public/user-data" import { isCloudVersion } from "@illa-public/utils" import { isEqual } from "lodash-es" import { FC, useCallback, useContext, useState } from "react" @@ -65,9 +68,11 @@ import { actionListEmptyStyle, addNewActionButtonStyle, createDropListItemContainerStyle, + dropListWithUpgradeIconStyle, listContainerStyle, listStyle, prefixIconContainerStyle, + upgradeContainerStyle, } from "./style" export const ActionListWithNewButton: FC = (props) => { @@ -81,6 +86,8 @@ export const ActionListWithNewButton: FC = (props) => { const [currentActionType, setCurrentActionType] = useState() const actionList = useSelector(getActionMixedList) + const teamInfo = useSelector(getCurrentTeamInfo)! + const upgradeModal = useUpgradeModal() const searchList = actionList.filter((value) => { return value.displayName @@ -167,6 +174,13 @@ export const ActionListWithNewButton: FC = (props) => { break } case "illadrive": { + if (!isSubscribeForUseDrive(teamInfo)) { + upgradeModal({ + modalType: "upgrade", + from: "drive_action", + }) + return + } const displayName = DisplayNameGenerator.generateDisplayName(type) const initialContent = getInitialContent(type) const baseData = generateBaseActionItem(displayName, "") @@ -302,11 +316,19 @@ export const ActionListWithNewButton: FC = (props) => { key="illaDrive" value="illaDrive" title={ -
- - {getIconFromResourceType("illadrive", "16px")} - - ILLA Drive +
+
+ + {getIconFromResourceType("illadrive", "16px")} + + ILLA Drive +
+ {!isSubscribeForUseDrive(teamInfo) && ( +
+ + {t("Upgrade")} +
+ )}
} onClick={handleClickActionType("illadrive")} diff --git a/apps/builder/src/page/App/components/Actions/ActionList/style.ts b/apps/builder/src/page/App/components/Actions/ActionList/style.ts index d0c7563a5b..413be34052 100644 --- a/apps/builder/src/page/App/components/Actions/ActionList/style.ts +++ b/apps/builder/src/page/App/components/Actions/ActionList/style.ts @@ -48,3 +48,19 @@ export const prefixIconContainerStyle = css` align-items: center; justify-content: center; ` + +export const dropListWithUpgradeIconStyle = css` + display: flex; + align-items: center; + justify-content: space-between; +` + +export const upgradeContainerStyle = css` + display: flex; + align-items: center; + gap: 4px; + color: ${getColor("techPurple", "03")}; + font-size: 12px; + font-style: normal; + line-height: 20px; +` diff --git a/apps/builder/src/page/App/components/ComponentPanel/ComponentItem.tsx b/apps/builder/src/page/App/components/ComponentPanel/ComponentItem.tsx index 6304ad5aa0..776f82a9b2 100644 --- a/apps/builder/src/page/App/components/ComponentPanel/ComponentItem.tsx +++ b/apps/builder/src/page/App/components/ComponentPanel/ComponentItem.tsx @@ -1,3 +1,7 @@ +import { UpgradeIcon } from "@illa-public/icon" +import { isSubscribeForUseDrive } from "@illa-public/upgrade-modal/utils" +import { getCurrentTeamInfo } from "@illa-public/user-data" +import { isCloudVersion } from "@illa-public/utils" import { FC, memo } from "react" import { useDrag } from "react-dnd" import { useSelector } from "react-redux" @@ -16,14 +20,20 @@ import { DRAG_EFFECT, DragInfo, } from "../ScaleSquare/components/DragContainer/interface" -import { iconStyle, itemContainerStyle, nameStyle } from "./style" +import { + iconStyle, + itemContainerStyle, + nameStyle, + upgradeIconStyle, +} from "./style" export const ComponentItem: FC = memo( (props: ComponentItemProps) => { - const { widgetName, widgetType, icon, displayName } = props + const { widgetName, widgetType, icon, displayName, isPremiumWidget } = props const isEditMode = useSelector(getIsILLAEditMode) const isGuideOpen = useSelector(getGuideStatus) + const teamInfo = useSelector(getCurrentTeamInfo)! const [, dragRef] = useDrag( () => ({ @@ -81,6 +91,13 @@ export const ComponentItem: FC = memo( css={iconStyle} {...(isGuideOpen ? { "data-onboarding-icon": widgetType } : {})} > + {isPremiumWidget && + isCloudVersion && + !isSubscribeForUseDrive(teamInfo) && ( + + + + )} {icon} {widgetName} diff --git a/apps/builder/src/page/App/components/ComponentPanel/ComponentSession.tsx b/apps/builder/src/page/App/components/ComponentPanel/ComponentSession.tsx index 87db6fe924..021f97c482 100644 --- a/apps/builder/src/page/App/components/ComponentPanel/ComponentSession.tsx +++ b/apps/builder/src/page/App/components/ComponentPanel/ComponentSession.tsx @@ -27,6 +27,7 @@ export const ComponentSession = memo((props: ComponentSessionProps) => { widgetType={item.widgetType} widgetName={item.widgetName} displayName={item.displayName} + isPremiumWidget={item.isPremiumWidget} /> ))}
diff --git a/apps/builder/src/page/App/components/ComponentPanel/componentListBuilder.tsx b/apps/builder/src/page/App/components/ComponentPanel/componentListBuilder.tsx index 5b0fa65a6a..191e059620 100644 --- a/apps/builder/src/page/App/components/ComponentPanel/componentListBuilder.tsx +++ b/apps/builder/src/page/App/components/ComponentPanel/componentListBuilder.tsx @@ -12,6 +12,7 @@ import { } from "@/widgetLibrary/widgetBuilder" export const DEPRECATED_WIDGETS = ["CHART", "TABLE_WIDGET"] +export const PREMIUM_WIDGETS = ["DRIVE_PICKER_WIDGET"] export type SessionType = keyof typeof sessionTypeMapSessionNameKey @@ -70,6 +71,7 @@ const translateChildren = (componentConfigs: WidgetConfig[]) => { widgetName, icon: item.icon, displayName, + isPremiumWidget: PREMIUM_WIDGETS.includes(type), } if (COMMONLY_WIDGET.has(type as string)) { sessionConfigs.COMMON.push(childrenConfig) diff --git a/apps/builder/src/page/App/components/ComponentPanel/interface.ts b/apps/builder/src/page/App/components/ComponentPanel/interface.ts index 497c407216..80f5355741 100644 --- a/apps/builder/src/page/App/components/ComponentPanel/interface.ts +++ b/apps/builder/src/page/App/components/ComponentPanel/interface.ts @@ -12,6 +12,7 @@ export interface WidgetCardInfo { widgetName: string widgetType: string icon: ReactNode + isPremiumWidget: boolean } export type ComponentSessionProps = { @@ -29,4 +30,5 @@ export interface ComponentItemProps { displayName: string widgetType: string icon: ReactNode + isPremiumWidget: boolean } diff --git a/apps/builder/src/page/App/components/ComponentPanel/style.tsx b/apps/builder/src/page/App/components/ComponentPanel/style.tsx index 2ab1b1c79c..8719585a28 100644 --- a/apps/builder/src/page/App/components/ComponentPanel/style.tsx +++ b/apps/builder/src/page/App/components/ComponentPanel/style.tsx @@ -1,5 +1,5 @@ import { css } from "@emotion/react" -import { globalColor, illaPrefix } from "@illa-design/react" +import { getColor, globalColor, illaPrefix } from "@illa-design/react" export const componentContainerStyle = css` border-top: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)}; @@ -70,7 +70,8 @@ export const iconStyle = css` color: ${globalColor(`--${illaPrefix}-grayBlue-04`)}; transition: background-color 200ms ease-in-out; padding: 8px; - + position: relative; + overflow: hidden; &:hover { background-color: ${globalColor(`--${illaPrefix}-grayBlue-08`)}; } @@ -95,3 +96,15 @@ export const emptyContainerStyle = css` align-items: center; justify-content: center; ` + +export const upgradeIconStyle = css` + position: absolute; + padding: 2px 8px; + top: 0; + left: 0; + color: ${getColor("techPurple", "03")}; + background-color: ${getColor("techPurple", "08")}; + display: flex; + align-items: center; + justify-content: center; +` diff --git a/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/SourceHeader/index.tsx b/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/SourceHeader/index.tsx index 9dd265ae2d..d098f8b99b 100644 --- a/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/SourceHeader/index.tsx +++ b/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/SourceHeader/index.tsx @@ -1,3 +1,4 @@ +import { useUpgradeModal } from "@illa-public/upgrade-modal" import { FC, useContext } from "react" import Folder from "@/assets/drive/panelFolder.svg?react" import { DriveFileSelectContext } from "@/components/DriveFileSelect" @@ -12,13 +13,26 @@ interface SourceHeaderProps { labelName?: string labelDesc?: string showSelect: boolean + canUseDrive: boolean } const SourceHeader: FC = ({ labelName, labelDesc, showSelect, + canUseDrive, }) => { + const upgradeModal = useUpgradeModal() const { setModalVisible } = useContext(DriveFileSelectContext) + const handleClickSelect = () => { + if (canUseDrive) { + setModalVisible(true) + } else { + upgradeModal({ + modalType: "upgrade", + from: "panel_setter_select", + }) + } + } return (
= ({ labelSize="medium" /> {showSelect && ( -
{ - setModalVisible(true) - }} - > +
diff --git a/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/UploadInput/index.tsx b/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/UploadInput/index.tsx index 0275efe7a8..955095dce3 100644 --- a/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/UploadInput/index.tsx +++ b/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/UploadInput/index.tsx @@ -1,3 +1,4 @@ +import { useUpgradeModal } from "@illa-public/upgrade-modal" import { FC, useContext } from "react" import { FolderOperateModalContext } from "@/components/FolderOperateModal/context" import { FileUploadContext } from "@/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/provider/FileUploadProvider" @@ -6,18 +7,26 @@ import { uploadContainerStyle, uploadIconStyle, uploadNameStyle } from "./style" interface UploadModeProps { widgetType: string + canUseDrive: boolean } -const UploadMode: FC = ({ widgetType }) => { +const UploadMode: FC = ({ widgetType, canUseDrive }) => { const placeholderInfo = getUploadModeInfo(widgetType) - + const upgradeModal = useUpgradeModal() const { uploadName, isUpLoading } = useContext(FileUploadContext) const { setFolderOperateVisible } = useContext(FolderOperateModalContext) + const handleClickUpload = () => { + if (canUseDrive) { + setFolderOperateVisible(true) + } else { + upgradeModal({ + modalType: "upgrade", + from: "panel_setter_upload", + }) + } + } return ( -
setFolderOperateVisible(true)} - > +
{placeholderInfo?.icon} {uploadName || placeholderInfo?.name}
diff --git a/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/index.tsx b/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/index.tsx index a74dba41c6..c4f4d5de6f 100644 --- a/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/index.tsx +++ b/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/index.tsx @@ -1,13 +1,18 @@ +import { UpgradeIcon } from "@illa-public/icon" +import { isSubscribeForUseDrive } from "@illa-public/upgrade-modal/utils" +import { getCurrentTeamInfo } from "@illa-public/user-data" import { get } from "lodash-es" import { FC, useMemo, useState } from "react" import { useTranslation } from "react-i18next" -import { RadioGroup } from "@illa-design/react" +import { useSelector } from "react-redux" +import { RadioGroup, getColor } from "@illa-design/react" import FilesModal, { ROOT_PATH } from "@/components/DriveFileSelect" import FolderOperateModal from "@/components/FolderOperateModal" import { applyRadioGroupWrapperStyle, baseRadioGroupContainerStyle, radioGroupStyle, + uploadButtonStyle, } from "@/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/style" import SourceHeader from "./components/SourceHeader" import URLModeInput from "./components/URLModeInput" @@ -31,6 +36,8 @@ const DriveSourceGroupSetter: FC = (props) => { } = props const { t } = useTranslation() + const teamInfo = useSelector(getCurrentTeamInfo)! + const canUseDrive = isSubscribeForUseDrive(teamInfo) const options = [ { @@ -38,7 +45,12 @@ const DriveSourceGroupSetter: FC = (props) => { value: DRIVE_SOURCE_MODE.URL, }, { - label: t("widget.public.select_options.upload"), + label: ( + + {!canUseDrive && } + {t("widget.public.select_options.upload")} + + ), value: DRIVE_SOURCE_MODE.UPLOAD, }, ] @@ -93,6 +105,7 @@ const DriveSourceGroupSetter: FC = (props) => { labelDesc={labelDesc} labelName={labelName} showSelect={selectMode === DRIVE_SOURCE_MODE.URL} + canUseDrive={canUseDrive} />
= (props) => { /> )} {selectMode === DRIVE_SOURCE_MODE.UPLOAD && ( - + )}
diff --git a/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/style.ts b/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/style.ts index cc37a758bd..1aa07ade86 100644 --- a/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/style.ts +++ b/apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/style.ts @@ -41,3 +41,11 @@ export const baseRadioGroupContainerStyle = ( width: 100%; ` } + +export const uploadButtonStyle = css` + display: flex; + align-items: center; + justify-content: center; + width: 100%; + gap: 4px; +` diff --git a/apps/builder/src/utils/action/premiumActionHandler.ts b/apps/builder/src/utils/action/premiumActionHandler.ts new file mode 100644 index 0000000000..33a26ec125 --- /dev/null +++ b/apps/builder/src/utils/action/premiumActionHandler.ts @@ -0,0 +1,28 @@ +import { ActionType } from "@illa-public/public-types" +import { createUpgradeModal } from "@illa-public/upgrade-modal" +import { isSubscribeForUseDrive } from "@illa-public/upgrade-modal/utils" +import { getCurrentTeamInfo } from "@illa-public/user-data" +import { isCloudVersion } from "@illa-public/utils" +import { getIsILLAProductMode } from "@/redux/config/configSelector" +import store from "@/store" + +export const PREMIUM_ACTIONS = ["illadrive"] + +export const isNeedPreventForPremium = (actionType: ActionType): boolean => { + const isProductionMode = getIsILLAProductMode(store.getState()) + if (isProductionMode) { + return false + } + if (isCloudVersion && PREMIUM_ACTIONS.includes(actionType)) { + const teamInfo = getCurrentTeamInfo(store.getState())! + const upgradeModal = createUpgradeModal() + if (!isSubscribeForUseDrive(teamInfo)) { + upgradeModal({ + modalType: "upgrade", + from: "drive_run_action", + }) + return true + } + } + return false +} diff --git a/apps/builder/src/utils/action/runAction.ts b/apps/builder/src/utils/action/runAction.ts index 5f9ba51ba3..5e60571156 100644 --- a/apps/builder/src/utils/action/runAction.ts +++ b/apps/builder/src/utils/action/runAction.ts @@ -30,6 +30,7 @@ import { } from "@/utils/typeHelper" import { fetchILLADriveClientResult } from "./driveActions" import { fetchS3ClientResult } from "./fetchS3ClientResult" +import { isNeedPreventForPremium } from "./premiumActionHandler" import { runActionErrorForColla } from "./runActionErrorForColla" import { runAllEventHandler } from "./runActionEventHandler" import { runTransformer } from "./runActionTransformer" @@ -66,7 +67,8 @@ export const fetchCommonActionResult = async ( abortSignal?: AbortSignal, ) => { const canSendRequest = checkCanSendRequest(actionType, actionContent) - if (!canSendRequest) { + const needPreventPremiumAction = isNeedPreventForPremium(actionType) + if (!canSendRequest || needPreventPremiumAction) { return Promise.reject(false) } diff --git a/apps/builder/src/utils/eventHandlerHelper/utils/driveUtils.ts b/apps/builder/src/utils/eventHandlerHelper/utils/driveUtils.ts index 3b43218595..31cc0a8106 100644 --- a/apps/builder/src/utils/eventHandlerHelper/utils/driveUtils.ts +++ b/apps/builder/src/utils/eventHandlerHelper/utils/driveUtils.ts @@ -17,6 +17,7 @@ import { uploadFileToDrive } from "@/utils/drive/upload/getSingedURL" import { getContentTypeByFileExtension, getFileName } from "@/utils/file" import { isBase64Simple } from "@/utils/url/base64" import { dataURLtoFile } from "@/widgetLibrary/UploadWidget/util" +import { isNeedPreventForPremium } from "./premiumEventUtils" const message = createMessage() @@ -34,7 +35,7 @@ export const downloadFromILLADrive = async ( params: IDownloadFromILLADriveParams, ) => { const { downloadInfo, asZip = false } = params - if (!Array.isArray(downloadInfo)) { + if (isNeedPreventForPremium() || !Array.isArray(downloadInfo)) { return } let promise = Promise.resolve() @@ -153,6 +154,7 @@ export const saveToILLADrive = async (params: ISaveToILLADriveParams) => { replace = false, } = params if ( + isNeedPreventForPremium() || typeof fileName !== "string" || fileData == undefined || typeof fileData !== "string" diff --git a/apps/builder/src/utils/eventHandlerHelper/utils/premiumEventUtils.ts b/apps/builder/src/utils/eventHandlerHelper/utils/premiumEventUtils.ts new file mode 100644 index 0000000000..3812f7a8d9 --- /dev/null +++ b/apps/builder/src/utils/eventHandlerHelper/utils/premiumEventUtils.ts @@ -0,0 +1,25 @@ +import { createUpgradeModal } from "@illa-public/upgrade-modal" +import { isSubscribeForUseDrive } from "@illa-public/upgrade-modal/utils" +import { getCurrentTeamInfo } from "@illa-public/user-data" +import { isCloudVersion } from "@illa-public/utils" +import { getIsILLAProductMode } from "@/redux/config/configSelector" +import store from "@/store" + +export const isNeedPreventForPremium = (): boolean => { + const isProductionMode = getIsILLAProductMode(store.getState()) + if (isProductionMode) { + return false + } + if (isCloudVersion) { + const teamInfo = getCurrentTeamInfo(store.getState())! + const upgradeModal = createUpgradeModal() + if (!isSubscribeForUseDrive(teamInfo)) { + upgradeModal({ + modalType: "upgrade", + from: "drive_run_event_handler", + }) + return true + } + } + return false +} diff --git a/apps/builder/src/widgetLibrary/DrivePickerWidget/drivePicker.tsx b/apps/builder/src/widgetLibrary/DrivePickerWidget/drivePicker.tsx index cd5da41021..50d4d026f7 100644 --- a/apps/builder/src/widgetLibrary/DrivePickerWidget/drivePicker.tsx +++ b/apps/builder/src/widgetLibrary/DrivePickerWidget/drivePicker.tsx @@ -1,10 +1,15 @@ import { EXPIRATION_TYPE } from "@illa-public/public-types" +import { useUpgradeModal } from "@illa-public/upgrade-modal" +import { isSubscribeForUseDrive } from "@illa-public/upgrade-modal/utils" +import { getCurrentTeamInfo } from "@illa-public/user-data" import { FC, useCallback } from "react" import { forwardRef, useContext } from "react" +import { useSelector } from "react-redux" import { Button } from "@illa-design/react" import FilesModal from "@/components/DriveFileSelect" import { DriveFileSelectContext } from "@/components/DriveFileSelect/context" import { FileToPanel } from "@/components/DriveFileSelect/interface" +import { getIsILLAProductMode } from "@/redux/config/configSelector" import { TooltipWrapper } from "@/widgetLibrary/PublicSector/TooltipWrapper" import { DEFAULT_EXPIRED_TIME } from "./constants" import { @@ -21,6 +26,24 @@ export const WrappedDrivePicker = forwardRef< >((props, ref) => { const { text, variant, colorScheme, disabled } = props const { setModalVisible } = useContext(DriveFileSelectContext) + const teamInfo = useSelector(getCurrentTeamInfo)! + const isProductionMode = useSelector(getIsILLAProductMode) + const upgradeModal = useUpgradeModal() + + const openLicenseDrawer = useCallback(() => { + upgradeModal({ + modalType: "upgrade", + from: "drive_picker", + }) + }, [upgradeModal]) + + const handleClick = () => { + if (isProductionMode || isSubscribeForUseDrive(teamInfo)) { + setModalVisible(true) + } else { + openLicenseDrawer() + } + } return (
@@ -30,7 +53,7 @@ export const WrappedDrivePicker = forwardRef< colorScheme={colorScheme} disabled={disabled} variant={variant} - onClick={() => setModalVisible(true)} + onClick={handleClick} > {text} diff --git a/packages/illa-public-component b/packages/illa-public-component index 1244a234cd..3de2d76884 160000 --- a/packages/illa-public-component +++ b/packages/illa-public-component @@ -1 +1 @@ -Subproject commit 1244a234cd41bb1030146f38819ffae49b24c608 +Subproject commit 3de2d768841911aa4910b53efa2b0c8d473ba4c9