From ed163c8a1c86b41fc94c2b7fdc5bf01e04bcec6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=98=86?= Date: Fri, 24 Dec 2021 11:14:07 +0800 Subject: [PATCH] [+] some widgets --- app/client/craco.common.config.js | 25 + app/client/craco.postcss.pxtorem.js | 342 +++++++++ app/client/package.json | 4 +- app/client/src/api/ApplicationApi.tsx | 10 +- .../src/assets/icons/control/line-through.svg | 5 + .../src/components/ads/ButtonTabComponent.tsx | 2 +- .../components/ads/ColorPickerComponent.tsx | 2 +- app/client/src/components/ads/Icon.tsx | 1 + .../src/components/ads/TreeDropdown.tsx | 2 +- .../designSystems/taro/ButtonComponent.tsx | 41 ++ .../designSystems/taro/GridComponent.tsx | 163 +++++ .../designSystems/taro/ImageComponent.tsx | 35 + .../designSystems/taro/ListComponent.tsx | 161 +++++ .../designSystems/taro/PickerComponent.tsx | 202 ++++++ .../designSystems/taro/PopoverComponent.tsx | 65 ++ .../designSystems/taro/SwiperComponent.tsx | 46 ++ .../designSystems/taro/TextComponent.tsx | 89 +++ .../editorComponents/DropTargetComponent.tsx | 10 +- .../WidgetNameComponent/SettingsControl.tsx | 5 + .../WidgetNameComponent/index.tsx | 3 +- app/client/src/constants/DefaultTheme.tsx | 6 +- app/client/src/constants/HelpConstants.ts | 52 ++ app/client/src/constants/WidgetConstants.tsx | 15 + app/client/src/constants/WidgetValidation.ts | 2 +- app/client/src/constants/routes.ts | 6 +- .../src/entities/DataTree/dataTreeFactory.ts | 4 +- app/client/src/icons/ControlIcons.tsx | 6 + app/client/src/icons/WidgetIcons.tsx | 65 ++ app/client/src/index.tsx | 23 +- .../mockResponses/WidgetConfigResponse.tsx | 166 +++++ .../mockResponses/WidgetSidebarResponse.tsx | 78 +++ app/client/src/pages/Applications/index.tsx | 124 ++-- .../Editor/Explorer/Widgets/WidgetEntity.tsx | 4 +- .../Explorer/Widgets/useNavigateToWidget.ts | 5 +- .../Editor/MainContainerLayoutControl.tsx | 21 +- .../Editor/PropertyPane/ConnectDataCTA.tsx | 1 + .../entityReducers/pageListReducer.tsx | 3 +- .../entityReducers/widgetConfigReducer.tsx | 27 + app/client/src/sagas/ApplicationSagas.tsx | 18 +- app/client/src/sagas/ModalSagas.ts | 20 +- app/client/src/sagas/PageSagas.tsx | 3 + app/client/src/sagas/selectors.tsx | 6 + app/client/src/selectors/editorSelectors.tsx | 10 +- app/client/src/selectors/entitiesSelector.ts | 5 +- app/client/src/selectors/widgetSelectors.ts | 12 +- app/client/src/utils/WidgetPropsUtils.tsx | 6 +- app/client/src/utils/WidgetRegistry.tsx | 221 ++++++ .../utils/autocomplete/EntityDefinitions.ts | 53 ++ .../autocomplete/dataTreeTypeDefCreator.ts | 4 +- app/client/src/widgets/BaseWidget.tsx | 1 + app/client/src/widgets/FormilyWidget.tsx | 1 - app/client/src/widgets/taro/ButtonWidget.tsx | 136 ++++ app/client/src/widgets/taro/CellWidget.tsx | 136 ++++ app/client/src/widgets/taro/GridWidget.tsx | 243 +++++++ app/client/src/widgets/taro/HtmlWidget.tsx | 55 ++ app/client/src/widgets/taro/ImageWidget.tsx | 136 ++++ app/client/src/widgets/taro/KVWidget.tsx | 136 ++++ app/client/src/widgets/taro/ListWidget.tsx | 220 ++++++ app/client/src/widgets/taro/PickerWidget.tsx | 82 +++ app/client/src/widgets/taro/PopupWidget.tsx | 178 +++++ .../src/widgets/taro/SimpleFormWidget.tsx | 139 ++++ app/client/src/widgets/taro/SwiperWidget.tsx | 63 ++ app/client/src/widgets/taro/TabsWidget.tsx | 136 ++++ app/client/src/widgets/taro/TextWidget.tsx | 202 ++++++ app/client/tsconfig.path.json | 4 +- app/client/yarn.lock | 656 ++++++++++++++---- .../server/configurations/CloudOSConfig.java | 3 + .../appsmith/server/domains/Application.java | 3 +- .../services/ApplicationPageServiceImpl.java | 14 +- .../solutions/CloudOSActionSolution.java | 15 +- .../src/main/resources/application.properties | 1 + app/server/envs/dev.env.example | 1 + 72 files changed, 4506 insertions(+), 234 deletions(-) create mode 100644 app/client/craco.postcss.pxtorem.js create mode 100644 app/client/src/assets/icons/control/line-through.svg create mode 100644 app/client/src/components/designSystems/taro/ButtonComponent.tsx create mode 100644 app/client/src/components/designSystems/taro/GridComponent.tsx create mode 100644 app/client/src/components/designSystems/taro/ImageComponent.tsx create mode 100644 app/client/src/components/designSystems/taro/ListComponent.tsx create mode 100644 app/client/src/components/designSystems/taro/PickerComponent.tsx create mode 100644 app/client/src/components/designSystems/taro/PopoverComponent.tsx create mode 100644 app/client/src/components/designSystems/taro/SwiperComponent.tsx create mode 100644 app/client/src/components/designSystems/taro/TextComponent.tsx create mode 100644 app/client/src/widgets/taro/ButtonWidget.tsx create mode 100644 app/client/src/widgets/taro/CellWidget.tsx create mode 100644 app/client/src/widgets/taro/GridWidget.tsx create mode 100644 app/client/src/widgets/taro/HtmlWidget.tsx create mode 100644 app/client/src/widgets/taro/ImageWidget.tsx create mode 100644 app/client/src/widgets/taro/KVWidget.tsx create mode 100644 app/client/src/widgets/taro/ListWidget.tsx create mode 100644 app/client/src/widgets/taro/PickerWidget.tsx create mode 100644 app/client/src/widgets/taro/PopupWidget.tsx create mode 100644 app/client/src/widgets/taro/SimpleFormWidget.tsx create mode 100644 app/client/src/widgets/taro/SwiperWidget.tsx create mode 100644 app/client/src/widgets/taro/TabsWidget.tsx create mode 100644 app/client/src/widgets/taro/TextWidget.tsx diff --git a/app/client/craco.common.config.js b/app/client/craco.common.config.js index 48a3d7df37..27e9dff73a 100644 --- a/app/client/craco.common.config.js +++ b/app/client/craco.common.config.js @@ -1,5 +1,7 @@ const CracoAlias = require("craco-alias"); const CracoLessPlugin = require('craco-less'); +const { DefinePlugin, EnvironmentPlugin } = require("webpack"); +const pxtorem = require("./craco.postcss.pxtorem"); module.exports = { plugins: [ @@ -35,4 +37,27 @@ module.exports = { }, }, ], + webpack: { + plugins: [ + new DefinePlugin({ + ENABLE_INNER_HTML: true, + ENABLE_ADJACENT_HTML: true, + ENABLE_TEMPLATE_CONTENT: true, + ENABLE_CLONE_NODE: true, + ENABLE_SIZE_APIS: false + }), + new EnvironmentPlugin({ + TARO_ENV: 'h5', + }), + ] + }, + style: { + postcss: { + plugins: [ + pxtorem({ + h5Width: 450, + }) + ] + } + }, }; diff --git a/app/client/craco.postcss.pxtorem.js b/app/client/craco.postcss.pxtorem.js new file mode 100644 index 0000000000..0a1683da4d --- /dev/null +++ b/app/client/craco.postcss.pxtorem.js @@ -0,0 +1,342 @@ +'use strict' + +const postcss = require('postcss') +const objectAssign = require('object-assign') +const pxRegex = /"[^"]+"|'[^']+'|url\([^\)]+\)|(\d*\.?\d+)px/g +/*eslint-disable*/ +const filterPropList = { + exact: function (list) { + return list.filter(function (m) { + return m.match(/^[^\*\!]+$/) + }) + }, + contain: function (list) { + return list.filter(function (m) { + return m.match(/^\*.+\*$/) + }).map(function (m) { + return m.substr(1, m.length - 2) + }) + }, + endWith: function (list) { + return list.filter(function (m) { + return m.match(/^\*[^\*]+$/) + }).map(function (m) { + return m.substr(1) + }) + }, + startWith: function (list) { + return list.filter(function (m) { + return m.match(/^[^\*\!]+\*$/) + }).map(function (m) { + return m.substr(0, m.length - 1) + }) + }, + notExact: function (list) { + return list.filter(function (m) { + return m.match(/^\![^\*].*$/) + }).map(function (m) { + return m.substr(1) + }) + }, + notContain: function (list) { + return list.filter(function (m) { + return m.match(/^\!\*.+\*$/) + }).map(function (m) { + return m.substr(2, m.length - 3) + }) + }, + notEndWith: function (list) { + return list.filter(function (m) { + return m.match(/^\!\*[^\*]+$/) + }).map(function (m) { + return m.substr(2) + }) + }, + notStartWith: function (list) { + return list.filter(function (m) { + return m.match(/^\![^\*]+\*$/) + }).map(function (m) { + return m.substr(1, m.length - 2) + }) + } +} + +const defaults = { + rootValue: 16, + unitPrecision: 5, + selectorBlackList: [], + propList: ['*'], + replace: true, + mediaQuery: false, + minPixelValue: 0 +} + +const legacyOptions = { + root_value: 'rootValue', + unit_precision: 'unitPrecision', + selector_black_list: 'selectorBlackList', + prop_white_list: 'propList', + media_query: 'mediaQuery', + propWhiteList: 'propList' +} + +const deviceRatio = { + 640: 2.34 / 2, + 750: 1, + 828: 1.81 / 2 +} + +// transform factor for fixed-width container +// (w / 320) * 20 * (pixels / rootValue) === (pixels / newRootValue) * 16 (default html font-size) +// so, newRootValue = (16 * 16 / w) * rootValue +const factor = 16 * 16 + +const baseFontSize = 40 + +const DEFAULT_WEAPP_OPTIONS = { + platform: 'h5', + designWidth: 750, + deviceRatio, + h5Width: 450, +} + +let targetUnit + +module.exports = postcss.plugin('postcss-pxtransform', function (options) { + options = Object.assign(DEFAULT_WEAPP_OPTIONS, options || {}) + + switch (options.platform) { + case 'weapp': { + options.rootValue = 1 / options.deviceRatio[options.designWidth] + targetUnit = 'rpx' + break + } + case 'h5': { + options.rootValue = (baseFontSize * options.designWidth / 640) * (factor / options.h5Width) + targetUnit = 'rem' + break + } + case 'rn': { + options.rootValue = options.deviceRatio[options.designWidth] * 2 + targetUnit = 'px' + break + } + } + + convertLegacyOptions(options) + + const opts = objectAssign({}, defaults, options) + const onePxTransform = typeof options.onePxTransform === 'undefined' ? true : options.onePxTransform + const pxReplace = createPxReplace(opts.rootValue, opts.unitPrecision, + opts.minPixelValue, onePxTransform) + + const satisfyPropList = createPropListMatcher(opts.propList) + + return function (css) { + // only transform taroify style + const filePath = css.source.input.file; + if (filePath.match(/^((?!@taroify).)*$/) !== null) { + return + } + + for (let i = 0; i < css.nodes.length; i++) { + if (css.nodes[i].type === 'comment') { + if (css.nodes[i].text === 'postcss-pxtransform disable') { + return + } else { + break + } + } + } + + // delete code between comment in RN + if (options.platform === 'rn') { + css.walkComments(comment => { + if (comment.text === 'postcss-pxtransform rn eject enable') { + let next = comment.next() + while (next) { + if (next.type === 'comment' && next.text === 'postcss-pxtransform rn eject disable') { + break + } + const temp = next.next() + next.remove() + next = temp + } + } + }) + } + + /* #ifdef %PLATFORM% */ + // 平台特有样式 + /* #endif */ + css.walkComments(comment => { + const wordList = comment.text.split(' ') + // 指定平台保留 + if (wordList.indexOf('#ifdef') > -1) { + // 非指定平台 + if (wordList.indexOf(options.platform) === -1) { + let next = comment.next() + while (next) { + if (next.type === 'comment' && next.text.trim() === '#endif') { + break + } + const temp = next.next() + next.remove() + next = temp + } + } + } + }) + + /* #ifndef %PLATFORM% */ + // 平台特有样式 + /* #endif */ + css.walkComments(comment => { + const wordList = comment.text.split(' ') + // 指定平台剔除 + if (wordList.indexOf('#ifndef') > -1) { + // 指定平台 + if (wordList.indexOf(options.platform) > -1) { + let next = comment.next() + while (next) { + if (next.type === 'comment' && next.text.trim() === '#endif') { + break + } + const temp = next.next() + next.remove() + next = temp + } + } + } + }) + + css.walkDecls(function (decl, i) { + // This should be the fastest test and will remove most declarations + if (decl.value.indexOf('px') === -1) return + + if (!satisfyPropList(decl.prop)) return + + if (blacklistedSelector(opts.selectorBlackList, + decl.parent.selector)) return + + const value = decl.value.replace(pxRegex, pxReplace) + + // if rem unit already exists, do not add or replace + if (declarationExists(decl.parent, decl.prop, value)) return + + if (opts.replace) { + decl.value = value + } else { + decl.parent.insertAfter(i, decl.clone({ value: value })) + } + }) + + if (opts.mediaQuery) { + css.walkAtRules('media', function (rule) { + if (rule.params.indexOf('px') === -1) return + rule.params = rule.params.replace(pxRegex, pxReplace) + }) + } + } +}) + +function convertLegacyOptions (options) { + if (typeof options !== 'object') return + if ( + ( + (typeof options.prop_white_list !== 'undefined' && + options.prop_white_list.length === 0) || + (typeof options.propWhiteList !== 'undefined' && + options.propWhiteList.length === 0) + ) && + typeof options.propList === 'undefined' + ) { + options.propList = ['*'] + delete options.prop_white_list + delete options.propWhiteList + } + Object.keys(legacyOptions).forEach(function (key) { + if (options.hasOwnProperty(key)) { + options[legacyOptions[key]] = options[key] + delete options[key] + } + }) +} + +function createPxReplace (rootValue, unitPrecision, minPixelValue, onePxTransform) { + return function (m, $1) { + if (!$1) return m + if (!onePxTransform && parseInt($1, 10) === 1) { + return m + } + const pixels = parseFloat($1) + if (pixels < minPixelValue) return m + const fixedVal = toFixed((pixels / rootValue), unitPrecision) + return (fixedVal === 0) ? '0' : fixedVal + targetUnit + } +} + +function toFixed (number, precision) { + const multiplier = Math.pow(10, precision + 1) + const wholeNumber = Math.floor(number * multiplier) + return Math.round(wholeNumber / 10) * 10 / multiplier +} + +function declarationExists (decls, prop, value) { + return decls.some(function (decl) { + return (decl.prop === prop && decl.value === value) + }) +} + +function blacklistedSelector (blacklist, selector) { + if (typeof selector !== 'string') return + return blacklist.some(function (regex) { + if (typeof regex === 'string') return selector.indexOf(regex) !== -1 + return selector.match(regex) + }) +} + +function createPropListMatcher (propList) { + const hasWild = propList.indexOf('*') > -1 + const matchAll = (hasWild && propList.length === 1) + const lists = { + exact: filterPropList.exact(propList), + contain: filterPropList.contain(propList), + startWith: filterPropList.startWith(propList), + endWith: filterPropList.endWith(propList), + notExact: filterPropList.notExact(propList), + notContain: filterPropList.notContain(propList), + notStartWith: filterPropList.notStartWith(propList), + notEndWith: filterPropList.notEndWith(propList) + } + return function (prop) { + if (matchAll) return true + return ( + ( + hasWild || + lists.exact.indexOf(prop) > -1 || + lists.contain.some(function (m) { + return prop.indexOf(m) > -1 + }) || + lists.startWith.some(function (m) { + return prop.indexOf(m) === 0 + }) || + lists.endWith.some(function (m) { + return prop.indexOf(m) === prop.length - m.length + }) + ) && + !( + lists.notExact.indexOf(prop) > -1 || + lists.notContain.some(function (m) { + return prop.indexOf(m) > -1 + }) || + lists.notStartWith.some(function (m) { + return prop.indexOf(m) === 0 + }) || + lists.notEndWith.some(function (m) { + return prop.indexOf(m) === prop.length - m.length + }) + ) + ) + } +} diff --git a/app/client/package.json b/app/client/package.json index 4b42f20a37..ae65bef14b 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -31,6 +31,8 @@ "@sentry/react": "^6.2.4", "@sentry/tracing": "^6.2.4", "@sentry/webpack-plugin": "^1.12.1", + "@taroify/core": "^0.0.21-alpha.0", + "@tarojs/components": "^3.3.14", "@types/chance": "^1.0.7", "@types/lodash": "^4.14.120", "@types/moment-timezone": "^0.5.10", @@ -103,7 +105,7 @@ "moment-timezone": "^0.5.27", "nanoid": "^2.0.4", "node-forge": "^0.10.0", - "node-sass": "^6.0.1", + "node-sass": "4.14.1", "normalizr": "^3.3.0", "path-to-regexp": "^6.2.0", "popper.js": "^1.15.0", diff --git a/app/client/src/api/ApplicationApi.tsx b/app/client/src/api/ApplicationApi.tsx index 21349820f9..44105969a7 100644 --- a/app/client/src/api/ApplicationApi.tsx +++ b/app/client/src/api/ApplicationApi.tsx @@ -51,6 +51,8 @@ export interface CreateApplicationRequest { orgId: string; color?: AppColorCode; icon?: AppIconName; + unpublishedAppLayout?: AppLayoutConfig; + publishedAppLayout?: AppLayoutConfig; } export interface SetDefaultPageRequest { @@ -171,7 +173,13 @@ class ApplicationApi extends Api { return Api.post( ApplicationApi.baseURL + ApplicationApi.createApplicationPath(request.orgId), - { name: request.name, color: request.color, icon: request.icon }, + { + name: request.name, + color: request.color, + icon: request.icon, + unpublishedAppLayout: request.unpublishedAppLayout, + publishedAppLayout: request.publishedAppLayout, + }, ); } diff --git a/app/client/src/assets/icons/control/line-through.svg b/app/client/src/assets/icons/control/line-through.svg new file mode 100644 index 0000000000..e17fc974e5 --- /dev/null +++ b/app/client/src/assets/icons/control/line-through.svg @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/app/client/src/components/ads/ButtonTabComponent.tsx b/app/client/src/components/ads/ButtonTabComponent.tsx index 4fe5bbe03f..f4461c3aaf 100644 --- a/app/client/src/components/ads/ButtonTabComponent.tsx +++ b/app/client/src/components/ads/ButtonTabComponent.tsx @@ -13,7 +13,7 @@ const ItemWrapper = styled.div<{ selected: boolean }>` ? props.theme.colors.propertyPane.activeButtonText : props.theme.colors.propertyPane.multiDropdownBoxHoverBg}; cursor: pointer; - &:first-of-type { + &:not(:last-of-type) { margin-right: 4px; } &&& svg { diff --git a/app/client/src/components/ads/ColorPickerComponent.tsx b/app/client/src/components/ads/ColorPickerComponent.tsx index c24d907c3e..546d89866e 100644 --- a/app/client/src/components/ads/ColorPickerComponent.tsx +++ b/app/client/src/components/ads/ColorPickerComponent.tsx @@ -186,7 +186,7 @@ function ColorPickerComponent(props: ColorPickerProps) { ) } onChange={handleChangeColor} - placeholder="enter color name or hex" + placeholder="输入web颜色名称,或者hex" value={color} /> props.theme.borderRadius}; font-size: 14px; - line-height: 14px; + line-height: 18px; display: flex; align-items: center; height: 30px; diff --git a/app/client/src/components/designSystems/taro/ButtonComponent.tsx b/app/client/src/components/designSystems/taro/ButtonComponent.tsx new file mode 100644 index 0000000000..fc3ee7e2d3 --- /dev/null +++ b/app/client/src/components/designSystems/taro/ButtonComponent.tsx @@ -0,0 +1,41 @@ +import React from "react"; +import { Button } from "@taroify/core"; + +interface ButtonComponentProps { + text?: string; + color?: string; + onClick?: any; + rounded?: boolean; + isDisabled?: boolean; + isLoading?: boolean; +} + +const ButtonComponent = ({ + text, + color, + onClick, + rounded, + isDisabled, + isLoading, +}: ButtonComponentProps) => { + const style = { + height: "100%", + backgroundColor: color || "var(--primary-color)", + color: "#fff", + }; + const shape = rounded ? "round" : "square"; + return ( + + ); +}; + +export default ButtonComponent; diff --git a/app/client/src/components/designSystems/taro/GridComponent.tsx b/app/client/src/components/designSystems/taro/GridComponent.tsx new file mode 100644 index 0000000000..0494f58009 --- /dev/null +++ b/app/client/src/components/designSystems/taro/GridComponent.tsx @@ -0,0 +1,163 @@ +import React, { useState } from "react"; +import { Text, View, ScrollView } from "@tarojs/components"; +import { Grid, Image, Button } from "@taroify/core"; +import { PhotoOutlined, ShoppingCartOutlined } from "@taroify/icons"; +import _ from "lodash"; +import styled from "styled-components"; + +export interface GridComponentProps { + list: any[]; + gridType: "I_N" | "I_N_D" | "I_N_D_B"; + urlKey: string; + titleKey: string; + descriptionKey?: string; + asPrice?: boolean; + priceUnit?: string; + buttonText?: string; + height?: string; + cols?: number; + gutter?: string; + bordered?: boolean; + titleColor?: string; + descriptionColor?: string; + buttonColor?: string; +} + +const SameHeightImage = styled(Image)<{ + height?: string; +}>` + height: ${(props) => props.height || "auto"}; +`; + +const Title = styled(Text)<{ + color?: string; +}>` + color: ${(props) => props.color || "#646566"}; + font-size: 16px; +`; + +const Container = styled(View)<{ + isBetween: boolean; +}>` + display: flex; + align-items: center; + justify-content: ${(props) => + props.isBetween ? "space-between" : "space-around"}; + margin-top: 8px; +`; + +const Price = styled(Text)<{ + color?: string; +}>` + color: ${(props) => props.color || "#DD4B34"}; + font-size: 14px; +`; + +const BuyButton = styled(Button)<{ + bgColor?: string; +}>` + background-color: ${(props) => props.bgColor || "#03b365"}; + color: #fff; + font-size: 14px; + padding: 0 8px; +`; + +const ColorGrid = styled(Grid)<{ + textColor?: string; +}>` + --grid-item-text-color: ${(props) => props.textColor}; +`; + +const GridComponent = (props: GridComponentProps) => { + const { + list, + gridType, + urlKey, + titleKey, + descriptionKey, + asPrice, + priceUnit, + buttonText, + height, + cols, + gutter, + bordered, + titleColor, + descriptionColor, + buttonColor, + } = props; + const items = _.isArray(list) ? list : []; + const key = urlKey + titleKey + items.length; + const isSimple = gridType === "I_N"; + + const onClickButton = (item: any) => (e: any) => { + e.stopPropagation(); + }; + + const onClickGridItem = (item: any) => (e: any) => { + console.log(item); + }; + + return ( + + + {items.map((item, index) => { + const url = item[urlKey]; + const title = item[titleKey] || ""; + const image = url ? ( + + ) : ( + + ); + if (isSimple) { + return ( + + ); + } + const description = item[descriptionKey || ""] || "描述"; + const price = asPrice ? priceUnit + description : description; + const priceView = {price}; + return ( + + {image} + + {title} + + {priceView} + {gridType === "I_N_D_B" ? ( + + {buttonText || } + + ) : null} + + + + ); + })} + + + ); +}; + +export default GridComponent; diff --git a/app/client/src/components/designSystems/taro/ImageComponent.tsx b/app/client/src/components/designSystems/taro/ImageComponent.tsx new file mode 100644 index 0000000000..03b5e4dbb8 --- /dev/null +++ b/app/client/src/components/designSystems/taro/ImageComponent.tsx @@ -0,0 +1,35 @@ +import React from "react"; +import { Image } from "@taroify/core"; + +interface ImageComponentProps { + imageUrl: string; + mode: any; + onClick?: any; + isCircle?: boolean; + radius?: string; +} + +const ImageComponent = ({ + imageUrl, + mode, + onClick, + isCircle, + radius, +}: ImageComponentProps) => { + const style = { + height: "100%", + width: "100%", + borderRadius: radius, + }; + return ( + + ); +}; + +export default ImageComponent; diff --git a/app/client/src/components/designSystems/taro/ListComponent.tsx b/app/client/src/components/designSystems/taro/ListComponent.tsx new file mode 100644 index 0000000000..dd3794a085 --- /dev/null +++ b/app/client/src/components/designSystems/taro/ListComponent.tsx @@ -0,0 +1,161 @@ +import React, { useState } from "react"; +import { Text, View, ScrollView } from "@tarojs/components"; +import { Cell, Image, Button } from "@taroify/core"; +import { PhotoOutlined, ShoppingCartOutlined } from "@taroify/icons"; +import _ from "lodash"; +import styled from "styled-components"; + +export interface ListComponentProps { + list: any[]; + contentType: "I_N_D_P_B" | "I_N_D" | "I_N_D_P"; + urlKey: string; + titleKey: string; + descriptionKey: string; + priceKey?: string; + buttonText?: string; + inset?: boolean; + width: string; + height: string; + titleColor?: string; + descriptionColor?: string; + priceColor?: string; + buttonColor?: string; +} + +const FreeImage = styled(Image)<{ + width: string; + height: string; +}>` + width: ${(props) => props.width}; + height: ${(props) => props.height}; +`; + +const RowCenter = styled(View)` + display: flex; + height: 100%; + flex-direction: column; + justify-content: center; +`; + +const Title = styled(Text)<{ + color?: string; +}>` + color: ${(props) => props.color || "#646566"}; + font-size: 16px; +`; + +const Description = styled(Text)<{ + color?: string; +}>` + color: ${(props) => props.color || "#646566"}; + font-size: 14px; +`; + +const Container = styled(View)` + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 8px; +`; + +const Price = styled(Text)<{ + color?: string; +}>` + color: ${(props) => props.color || "#DD4B34"}; + font-size: 14px; +`; + +const BuyButton = styled(Button)<{ + bgColor?: string; +}>` + background-color: ${(props) => props.bgColor || "#03b365"}; + color: #fff; + font-size: 14px; + padding: 0 8px; +`; + +const ListComponent = (props: ListComponentProps) => { + const { + list, + contentType, + urlKey, + titleKey, + descriptionKey, + priceKey, + buttonText, + inset, + width, + height, + titleColor, + descriptionColor, + priceColor, + buttonColor, + } = props; + const items = _.isArray(list) ? list : []; + const noPrice = contentType === "I_N_D"; + const hasButton = contentType === "I_N_D_P_B"; + + const onClickButton = (item: any) => (e: any) => { + e.stopPropagation(); + }; + + const onClickItem = (item: any) => (e: any) => { + console.log(item); + }; + + return ( + + + {items.map((item, index) => { + const url = item[urlKey]; + const title = item[titleKey] || ""; + const description = item[descriptionKey] || "描述"; + const price = `¥${item[priceKey || ""] || "168"}`; + const image = url ? ( + + ) : ( + width ? height : width} + style={{ height, width }} + /> + ); + const priceView = {price}; + return ( + + + {title} + + + {description} + + + {noPrice ? null : ( + + {priceView} + {hasButton ? ( + + {buttonText || } + + ) : null} + + )} + + + ); + })} + + + ); +}; + +export default ListComponent; diff --git a/app/client/src/components/designSystems/taro/PickerComponent.tsx b/app/client/src/components/designSystems/taro/PickerComponent.tsx new file mode 100644 index 0000000000..849e108db8 --- /dev/null +++ b/app/client/src/components/designSystems/taro/PickerComponent.tsx @@ -0,0 +1,202 @@ +import React, { useState } from "react"; +import { View, Text } from "@tarojs/components"; +import VirtualList from "@tarojs/components/virtual-list"; +import Taro from "@tarojs/taro"; +import { + Uploader, + Cell, + Button, + Image, + Toast, + Checkbox, + Field, + NoticeBar, + Flex, + Dialog, +} from "@taroify/core"; +import { Arrow } from "@taroify/icons"; + +interface PickerComponentProps { + title?: string; + onButtonClick?: (e: any) => void; +} + +function buildData(offset = 0) { + return Array(100) + .fill(0) + .map((_, i) => i + offset); +} + +const Row = React.memo(({ id, index, style, data }: any) => { + return ( + + Row {index} : {data[index]} + + ); +}); +Row.displayName = "Row"; + +const PickerComponent = (props: PickerComponentProps) => { + const { title, onButtonClick } = props; + + const [loading, setLoading] = useState(false); + const [data, setData] = useState(buildData(0)); + const listReachBottom = () => { + // 如果 loading 与视图相关,那它就应该放在 `this.state` 里 + // 我们这里使用的是一个同步的 API 调用 loading,所以不需要 + setLoading(true); + setTimeout(() => { + setData(data.concat(buildData(data.length))); + setLoading(false); + }, 1000); + }; + const dataLen = data.length; + const itemSize = 100; + + const [open, setOpen] = useState(false); + const [value, setValue] = useState(); + const [text, setText] = useState(""); + const [idcard, setIdcard] = useState(""); + const [number, setNumber] = useState(""); + const [digit, setDigit] = useState(""); + const [password, setPassword] = useState(""); + + const [file, setFile] = useState(); + + const onUpload = () => { + Taro.chooseImage({ + count: 1, + sizeType: ["original", "compressed"], + sourceType: ["album", "camera"], + }).then(({ tempFiles }) => { + setFile({ + url: tempFiles[0].path, + type: tempFiles[0].type, + name: tempFiles[0].originalFileObj?.name, + }); + }); + }; + + const show = () => { + Taro.showToast({ + title: "生活愉快!", + icon: "success", + duration: 2000, + }); + }; + + return ( + + + + + + + + + } + clickable + onClick={() => setOpen(true)} + > + 内容 + + + + } clickable> + 内容 + + + + + + + + + + + 复选框 a + 复选框 b + + +
+ +
+ + + setText(e.detail.value)} + /> + setIdcard(e.detail.value)} + /> + setNumber(e.detail.value)} + /> + setDigit(e.detail.value)} + /> + setPassword(e.detail.value)} + /> + + + + {title} + + + + {title} + + 代码是写出来给人看的,附带能在机器上运行 + + + + + + + +
+ ); +}; + +export default PickerComponent; diff --git a/app/client/src/components/designSystems/taro/PopoverComponent.tsx b/app/client/src/components/designSystems/taro/PopoverComponent.tsx new file mode 100644 index 0000000000..64dae072af --- /dev/null +++ b/app/client/src/components/designSystems/taro/PopoverComponent.tsx @@ -0,0 +1,65 @@ +import React, { ReactNode, useEffect } from "react"; +import styled from "styled-components"; +import { getCanvasClassName } from "utils/generators"; +import { Popup } from "@taroify/core"; +import { Cross } from "@taroify/icons"; +import { PopupProps } from "@taroify/core/popup/popup"; + +const PopupContainer = styled(Popup)< + { + height?: number; + } & PopupProps +>` + height: ${(props) => props.height}px; + overflow: visible; + width: 450px; + left: unset; + background: #f6f6f6; +`; + +const Content = styled.div` + width: 100%; + height: 100%; +`; + +export type ModalComponentProps = { + isOpen: boolean; + onClose: (e: any) => void; + onModalClose?: () => void; + children: ReactNode; + className?: string; + canOutsideClickClose: boolean; + rounded?: boolean; + height?: number; +}; + +/* eslint-disable react/display-name */ +export function ModalComponent(props: ModalComponentProps) { + useEffect(() => { + return () => { + if (props.onModalClose) props.onModalClose(); + }; + }, []); + return ( + + + + + + + {props.children} + + + ); +} + +export default ModalComponent; diff --git a/app/client/src/components/designSystems/taro/SwiperComponent.tsx b/app/client/src/components/designSystems/taro/SwiperComponent.tsx new file mode 100644 index 0000000000..4f940dce05 --- /dev/null +++ b/app/client/src/components/designSystems/taro/SwiperComponent.tsx @@ -0,0 +1,46 @@ +import React, { useState } from "react"; +import { Navigator } from "@tarojs/components"; +import { Swiper, Image } from "@taroify/core"; +import _ from "lodash"; +import styled from "styled-components"; + +interface SwiperComponentProps { + list: any[]; + urlKey: string; +} + +const Empty = styled.div` + display: flex; + align-items: center; + justify-content: center; + font-size: 32px; + color: #fff; + background: var(--primary-color); + height: 100%; +`; + +const SwiperComponent = (props: SwiperComponentProps) => { + const { list, urlKey } = props; + const items = _.isArray(list) ? list : []; + const key = urlKey + items.length; + return ( + + + {items.map((item, index) => { + const url = _.isString(item) ? item : item[urlKey]; + const content = url ? ( + + ) : ( + {index + 1} + ); + return ( + + {content} + + ); + })} + + ); +}; + +export default SwiperComponent; diff --git a/app/client/src/components/designSystems/taro/TextComponent.tsx b/app/client/src/components/designSystems/taro/TextComponent.tsx new file mode 100644 index 0000000000..1438a98c79 --- /dev/null +++ b/app/client/src/components/designSystems/taro/TextComponent.tsx @@ -0,0 +1,89 @@ +import * as React from "react"; +import { Text, View } from "@tarojs/components"; +import styled from "styled-components"; +import { ComponentProps } from "components/designSystems/appsmith/BaseComponent"; +import { TextAlign } from "widgets/TextWidget"; +import { + FontStyleTypes, + TextSize, + TEXT_SIZES, +} from "constants/WidgetConstants"; + +export const TextContainer = styled(View)` + height: 100%; + width: 100%; +`; + +export const StyledText = styled(Text)<{ + scroll: boolean; + textAlign: string; + backgroundColor?: string; + textColor?: string; + fontStyle?: string; + fontSize?: TextSize; +}>` + height: 100%; + overflow-y: ${(props) => (props.scroll ? "auto" : "hidden")}; + text-overflow: ellipsis; + text-align: ${(props) => props.textAlign.toLowerCase()}; + display: flex; + width: 100%; + justify-content: ${(props) => + props.textAlign === "LEFT" + ? "flex-start" + : props.textAlign === "RIGHT" + ? "flex-end" + : "center"}; + align-items: ${(props) => (props.scroll ? "flex-start" : "center")}; + background: ${(props) => props?.backgroundColor}; + color: ${(props) => props?.textColor}; + font-style: ${(props) => + props?.fontStyle?.includes(FontStyleTypes.ITALIC) ? "italic" : ""}; + text-decoration: ${(props) => + props?.fontStyle?.includes(FontStyleTypes.LINETHROUGH) + ? "line-through" + : ""}; + font-weight: ${(props) => + props?.fontStyle?.includes(FontStyleTypes.BOLD) ? "bold" : "normal"}; + font-size: ${(props) => props?.fontSize && TEXT_SIZES[props?.fontSize]}; +`; + +export interface TextComponentProps extends ComponentProps { + text?: string; + textAlign: TextAlign; + fontSize?: TextSize; + isLoading: boolean; + shouldScroll?: boolean; + backgroundColor?: string; + textColor?: string; + fontStyle?: string; +} + +class TextComponent extends React.Component { + render() { + const { + backgroundColor, + fontSize, + fontStyle, + text, + textAlign, + textColor, + } = this.props; + return ( + + + {text} + + + ); + } +} + +export default TextComponent; diff --git a/app/client/src/components/editorComponents/DropTargetComponent.tsx b/app/client/src/components/editorComponents/DropTargetComponent.tsx index b44c1974fa..ed32a4be28 100644 --- a/app/client/src/components/editorComponents/DropTargetComponent.tsx +++ b/app/client/src/components/editorComponents/DropTargetComponent.tsx @@ -63,7 +63,7 @@ const EmptyContainer = styled.div` width: 400px; height: 400px; margin-top: -180px; - margin-left: -100px; + margin-left: -70px; text-align: center; opacity: 0.5; @@ -74,6 +74,7 @@ const EmptyContainer = styled.div` & img { height: 100%; + width: 70%; } `; @@ -219,12 +220,17 @@ export function DropTargetComponent(props: DropTargetComponentProps) { // Only show propertypane if this is a new widget. // If it is not a new widget, then let the DraggableComponent handle it. // Give evaluations a second to complete. + const waitingTime = + widget.type === WidgetTypes.MODAL_WIDGET || + widget.type === WidgetTypes.TARO_POPUP_WIDGET + ? 1000 + : 100; setTimeout(() => { if (showPropertyPane && updateWidgetParams.payload.newWidgetId) { showPropertyPane(updateWidgetParams.payload.newWidgetId); // toggleEditWidgetName(updateWidgetParams.payload.newWidgetId, true); } - }, 100); + }, waitingTime); // Select the widget if it is a new widget selectWidget && selectWidget(widget.widgetId); diff --git a/app/client/src/components/editorComponents/WidgetNameComponent/SettingsControl.tsx b/app/client/src/components/editorComponents/WidgetNameComponent/SettingsControl.tsx index e4bd7df694..ed0ebcbd43 100644 --- a/app/client/src/components/editorComponents/WidgetNameComponent/SettingsControl.tsx +++ b/app/client/src/components/editorComponents/WidgetNameComponent/SettingsControl.tsx @@ -96,6 +96,11 @@ const getStyles = ( background: Colors.OUTER_SPACE, color: Colors.WHITE, }; + default: + return { + background: Colors.OUTER_SPACE, + color: Colors.WHITE, + }; } }; diff --git a/app/client/src/components/editorComponents/WidgetNameComponent/index.tsx b/app/client/src/components/editorComponents/WidgetNameComponent/index.tsx index f0d75a9e2e..5b0be9a2ff 100644 --- a/app/client/src/components/editorComponents/WidgetNameComponent/index.tsx +++ b/app/client/src/components/editorComponents/WidgetNameComponent/index.tsx @@ -132,7 +132,8 @@ export function WidgetNameComponent(props: WidgetNameComponentProps) { !!props.errorCount; let currentActivity = - props.type === WidgetTypes.MODAL_WIDGET + props.type === WidgetTypes.MODAL_WIDGET || + props.type === WidgetTypes.TARO_POPUP_WIDGET ? Activities.HOVERING : Activities.NONE; if (focusedWidget === props.widgetId) currentActivity = Activities.HOVERING; diff --git a/app/client/src/constants/DefaultTheme.tsx b/app/client/src/constants/DefaultTheme.tsx index 186915089b..93566c7995 100644 --- a/app/client/src/constants/DefaultTheme.tsx +++ b/app/client/src/constants/DefaultTheme.tsx @@ -2596,6 +2596,10 @@ export const theme: Theme = { }, }; -export { css, createGlobalStyle, keyframes, ThemeProvider }; +const taroifyTheme = { + primaryColor: Colors.MINT_GREEN, +}; + +export { css, createGlobalStyle, keyframes, ThemeProvider, taroifyTheme }; export default styled; diff --git a/app/client/src/constants/HelpConstants.ts b/app/client/src/constants/HelpConstants.ts index 9e636da534..0d63b5e781 100644 --- a/app/client/src/constants/HelpConstants.ts +++ b/app/client/src/constants/HelpConstants.ts @@ -139,6 +139,58 @@ export const HelpMap = { path: "/widget-reference/", searchKey: "Formily", }, + TARO_PICKER_WIDGET: { + path: "/widget-reference/", + searchKey: "Taro Picker", + }, + TARO_SWIPER_WIDGET: { + path: "/widget-reference/", + searchKey: "Taro Swiper", + }, + TARO_GRID_WIDGET: { + path: "/widget-reference/", + searchKey: "Taro Grid", + }, + TARO_LIST_WIDGET: { + path: "/widget-reference/", + searchKey: "Taro List", + }, + TARO_TEXT_WIDGET: { + path: "/widget-reference/", + searchKey: "Taro Text", + }, + TARO_POPUP_WIDGET: { + path: "/widget-reference/", + searchKey: "Taro Popup", + }, + TARO_BUTTON_WIDGET: { + path: "/widget-reference/", + searchKey: "Taro Button", + }, + TARO_IMAGE_WIDGET: { + path: "/widget-reference/", + searchKey: "Taro Image", + }, + TARO_CELL_WIDGET: { + path: "/widget-reference/", + searchKey: "Taro Cell", + }, + TARO_HTML_WIDGET: { + path: "/widget-reference/", + searchKey: "Taro Html", + }, + TARO_SIMPLE_FORM_WIDGET: { + path: "/widget-reference/", + searchKey: "Taro Simple Form", + }, + TARO_KV_WIDGET: { + path: "/widget-reference/", + searchKey: "Taro KV", + }, + TARO_TABS_WIDGET: { + path: "/widget-reference/", + searchKey: "Taro Tabs", + }, }; export const HelpBaseURL = "https://docs.appsmith.com"; diff --git a/app/client/src/constants/WidgetConstants.tsx b/app/client/src/constants/WidgetConstants.tsx index 68d07d1db2..510fe1b962 100644 --- a/app/client/src/constants/WidgetConstants.tsx +++ b/app/client/src/constants/WidgetConstants.tsx @@ -33,6 +33,19 @@ export enum WidgetTypes { DIVIDER_WIDGET = "DIVIDER_WIDGET", MENU_BUTTON_WIDGET = "MENU_BUTTON_WIDGET", FORMILY_WIDGET = "FORMILY_WIDGET", + TARO_PICKER_WIDGET = "TARO_PICKER_WIDGET", + TARO_SWIPER_WIDGET = "TARO_SWIPER_WIDGET", + TARO_GRID_WIDGET = "TARO_GRID_WIDGET", + TARO_TEXT_WIDGET = "TARO_TEXT_WIDGET", + TARO_LIST_WIDGET = "TARO_LIST_WIDGET", + TARO_POPUP_WIDGET = "TARO_POPUP_WIDGET", + TARO_IMAGE_WIDGET = "TARO_IMAGE_WIDGET", + TARO_BUTTON_WIDGET = "TARO_BUTTON_WIDGET", + TARO_CELL_WIDGET = "TARO_CELL_WIDGET", + TARO_HTML_WIDGET = "TARO_HTML_WIDGET", + TARO_SIMPLE_FORM_WIDGET = "TARO_SIMPLE_FORM_WIDGET", + TARO_KV_WIDGET = "TARO_KV_WIDGET", + TARO_TABS_WIDGET = "TARO_TABS_WIDGET", } export type WidgetType = keyof typeof WidgetTypes; @@ -100,6 +113,7 @@ export const layoutConfigurations: LayoutConfigurations = { DESKTOP: { minWidth: 1160, maxWidth: 1280 }, TABLET: { minWidth: 650, maxWidth: 800 }, FLUID: { minWidth: -1, maxWidth: -1 }, + MOBILE_FLUID: { minWidth: 450, maxWidth: 450 }, }; export const LATEST_PAGE_VERSION = 30; @@ -136,6 +150,7 @@ export enum FontStyleTypes { ITALIC = "ITALIC", REGULAR = "REGULAR", UNDERLINE = "UNDERLINE", + LINETHROUGH = "LINETHROUGH", } export enum TextSizes { diff --git a/app/client/src/constants/WidgetValidation.ts b/app/client/src/constants/WidgetValidation.ts index d740138d7c..18cf347f03 100644 --- a/app/client/src/constants/WidgetValidation.ts +++ b/app/client/src/constants/WidgetValidation.ts @@ -82,7 +82,7 @@ export const JAVASCRIPT_KEYWORDS = { export const DATA_TREE_KEYWORDS = { actionPaths: "actionPaths", - appsmith: "appsmith", + global: "global", pageList: "pageList", [EXECUTION_PARAM_KEY]: EXECUTION_PARAM_KEY, }; diff --git a/app/client/src/constants/routes.ts b/app/client/src/constants/routes.ts index 74d3f470ba..c7c7fb4131 100644 --- a/app/client/src/constants/routes.ts +++ b/app/client/src/constants/routes.ts @@ -207,7 +207,11 @@ export const GEN_TEMPLATE_FORM_ROUTE = "/form"; export const getGenerateTemplateURL = ( applicationId = ":applicationId", pageId = ":pageId", -): string => `${BUILDER_PAGE_URL(applicationId, pageId)}${GEN_TEMPLATE_URL}`; + isMobile = false, +): string => + `${BUILDER_PAGE_URL(applicationId, pageId)}${ + isMobile ? "" : GEN_TEMPLATE_URL + }`; export const getGenerateTemplateFormURL = ( applicationId = ":applicationId", diff --git a/app/client/src/entities/DataTree/dataTreeFactory.ts b/app/client/src/entities/DataTree/dataTreeFactory.ts index 69f14f317c..8363f57c43 100644 --- a/app/client/src/entities/DataTree/dataTreeFactory.ts +++ b/app/client/src/entities/DataTree/dataTreeFactory.ts @@ -124,13 +124,13 @@ export class DataTreeFactory { }); dataTree.pageList = pageList; - dataTree.appsmith = { + dataTree.global = { ...appData, // combine both persistent and transient state with the transient state // taking precedence in case the key is the same store: { ...appData.store.persistent, ...appData.store.transient }, } as DataTreeAppsmith; - (dataTree.appsmith as DataTreeAppsmith).ENTITY_TYPE = ENTITY_TYPE.APPSMITH; + (dataTree.global as DataTreeAppsmith).ENTITY_TYPE = ENTITY_TYPE.APPSMITH; return dataTree; } } diff --git a/app/client/src/icons/ControlIcons.tsx b/app/client/src/icons/ControlIcons.tsx index 7dd974aee9..878fa14a36 100644 --- a/app/client/src/icons/ControlIcons.tsx +++ b/app/client/src/icons/ControlIcons.tsx @@ -28,6 +28,7 @@ import { ReactComponent as HideColumnIcon } from "assets/icons/control/columns-v import { ReactComponent as DeleteColumnIcon } from "assets/icons/control/delete-column.svg"; import { ReactComponent as BoldFontIcon } from "assets/icons/control/bold.svg"; import { ReactComponent as ItalicsFontIcon } from "assets/icons/control/italics.svg"; +import { ReactComponent as LineThroughFontIcon } from "assets/icons/control/line-through.svg"; import { ReactComponent as LeftAlignIcon } from "assets/icons/control/left-align.svg"; import { ReactComponent as CenterAlignIcon } from "assets/icons/control/center-align.svg"; import { ReactComponent as RightAlignIcon } from "assets/icons/control/right-align.svg"; @@ -206,6 +207,11 @@ export const ControlIcons: { ), + LINETHROUGH_FONT: (props: IconProps) => ( + + + + ), LEFT_ALIGN: (props: IconProps) => ( diff --git a/app/client/src/icons/WidgetIcons.tsx b/app/client/src/icons/WidgetIcons.tsx index c53c087675..43794dd4ac 100644 --- a/app/client/src/icons/WidgetIcons.tsx +++ b/app/client/src/icons/WidgetIcons.tsx @@ -178,6 +178,71 @@ export const WidgetIcons: { ), + TARO_PICKER_WIDGET: (props: IconProps) => ( + + + + ), + TARO_SWIPER_WIDGET: (props: IconProps) => ( + + + + ), + TARO_GRID_WIDGET: (props: IconProps) => ( + + + + ), + TARO_TEXT_WIDGET: (props: IconProps) => ( + + + + ), + TARO_LIST_WIDGET: (props: IconProps) => ( + + + + ), + TARO_POPUP_WIDGET: (props: IconProps) => ( + + + + ), + TARO_IMAGE_WIDGET: (props: IconProps) => ( + + + + ), + TARO_BUTTON_WIDGET: (props: IconProps) => ( + + + + ), + TARO_CELL_WIDGET: (props: IconProps) => ( + + + + ), + TARO_HTML_WIDGET: (props: IconProps) => ( + + + + ), + TARO_SIMPLE_FORM_WIDGET: (props: IconProps) => ( + + + + ), + TARO_KV_WIDGET: (props: IconProps) => ( + + + + ), + TARO_TABS_WIDGET: (props: IconProps) => ( + + + + ), }; export type WidgetIcon = typeof WidgetIcons[keyof typeof WidgetIcons]; diff --git a/app/client/src/index.tsx b/app/client/src/index.tsx index 5002fed349..0dbb728c2e 100755 --- a/app/client/src/index.tsx +++ b/app/client/src/index.tsx @@ -3,7 +3,7 @@ import "./wdyr"; import ReactDOM from "react-dom"; import { Provider } from "react-redux"; import "./index.less"; -import { ThemeProvider } from "constants/DefaultTheme"; +import { ThemeProvider, taroifyTheme } from "constants/DefaultTheme"; import { appInitializer } from "utils/AppsmithUtils"; import { Slide } from "react-toastify"; import store from "./store"; @@ -17,6 +17,8 @@ import { setThemeMode } from "actions/themeActions"; import { StyledToastContainer } from "components/ads/Toast"; import localStorage from "utils/localStorage"; import "./polyfills/corejs-add-on"; +import AppErrorBoundary from "./AppErrorBoundry"; +import GlobalStyles from "globalStyles"; // locale import { ConfigProvider } from "antd"; import zhCNAntd from "antd/lib/locale/zh_CN"; @@ -27,9 +29,20 @@ import "moment/locale/zh-cn"; import { setAutoFreeze } from "immer"; const shouldAutoFreeze = process.env.NODE_ENV === "development"; setAutoFreeze(shouldAutoFreeze); +// taro-components polyfills +import { ConfigProvider as TaroifyTheme } from "@taroify/core"; +import { + applyPolyfills, + defineCustomElements, +} from "@tarojs/components/loader"; +import "@tarojs/components/dist/taro-components/taro-components.css"; +import "@taroify/icons/index.scss"; +import "@taroify/core/index.scss"; +applyPolyfills().then(() => { + defineCustomElements(window); +}); -import AppErrorBoundary from "./AppErrorBoundry"; -import GlobalStyles from "globalStyles"; +// app init appInitializer(); function App() { @@ -68,7 +81,9 @@ class ThemedApp extends React.Component<{ - + + + diff --git a/app/client/src/mockResponses/WidgetConfigResponse.tsx b/app/client/src/mockResponses/WidgetConfigResponse.tsx index 96fbb6b277..0bd7d498c5 100644 --- a/app/client/src/mockResponses/WidgetConfigResponse.tsx +++ b/app/client/src/mockResponses/WidgetConfigResponse.tsx @@ -1231,6 +1231,172 @@ const WidgetConfigResponse: WidgetConfigReducerState = { showReset: true, resetLabel: "重置", }, + [WidgetTypes.TARO_PICKER_WIDGET]: { + widgetName: "m_picker", + rows: 2 * GRID_DENSITY_MIGRATION_V1, + columns: 4 * GRID_DENSITY_MIGRATION_V1, + title: "喵喵", + }, + [WidgetTypes.TARO_SWIPER_WIDGET]: { + widgetName: "m_swiper", + rows: 6 * GRID_DENSITY_MIGRATION_V1, + columns: 16 * GRID_DENSITY_MIGRATION_V1, + list: [ + { url: "https://img01.yzcdn.cn/vant/apple-1.jpg" }, + { url: "https://img01.yzcdn.cn/vant/apple-2.jpg" }, + { url: "https://img01.yzcdn.cn/vant/apple-3.jpg" }, + { url: "https://img01.yzcdn.cn/vant/apple-4.jpg" }, + ], + urlKey: "url", + }, + [WidgetTypes.TARO_GRID_WIDGET]: { + widgetName: "m_grid", + rows: 6 * GRID_DENSITY_MIGRATION_V1, + columns: 16 * GRID_DENSITY_MIGRATION_V1, + list: [ + { url: "", name: "文本" }, + { url: "", name: "文本" }, + { url: "", name: "文本" }, + { url: "", name: "文本" }, + { url: "", name: "文本" }, + { url: "", name: "文本" }, + ], + urlKey: "url", + titleKey: "name", + cols: 4, + gutter: "0", + bordered: true, + gridType: "I_N", + titleColor: "#646566", + descriptionColor: "#DD4B34", + buttonColor: "#03b365", + priceUnit: "¥", + }, + [WidgetTypes.TARO_TEXT_WIDGET]: { + widgetName: "m_text", + text: "文本", + fontSize: "PARAGRAPH", + textAlign: "LEFT", + textColor: Colors.THUNDER, + rows: 1 * GRID_DENSITY_MIGRATION_V1, + columns: 4 * GRID_DENSITY_MIGRATION_V1, + version: 1, + }, + [WidgetTypes.TARO_LIST_WIDGET]: { + widgetName: "m_list", + rows: 6 * GRID_DENSITY_MIGRATION_V1, + columns: 16 * GRID_DENSITY_MIGRATION_V1, + list: [ + { url: "", name: "标题", description: "描述" }, + { url: "", name: "标题", description: "描述" }, + { url: "", name: "标题", description: "描述" }, + { url: "", name: "标题", description: "描述" }, + ], + urlKey: "url", + titleKey: "name", + descriptionKey: "description", + contentType: "I_N_D", + width: "100px", + height: "80px", + inset: false, + titleColor: "#646566", + descriptionColor: "#999", + priceColor: "#DD4B34", + buttonColor: "#03b365", + }, + [WidgetTypes.TARO_POPUP_WIDGET]: { + widgetName: "m_popup", + rows: 10 * GRID_DENSITY_MIGRATION_V1, + columns: 12 * GRID_DENSITY_MIGRATION_V1, + // detachFromLayout is set true for widgets that are not bound to the widgets within the layout. + // setting it to true will only render the widgets(from sidebar) on the main container without any collision check. + detachFromLayout: true, + canOutsideClickClose: true, + rounded: true, + height: 400, + children: [], + version: 1, + blueprint: { + view: [ + { + type: "CANVAS_WIDGET", + position: { left: 0, top: 0 }, + props: { + detachFromLayout: true, + canExtend: false, + isVisible: true, + isDisabled: false, + shouldScrollContents: false, + children: [], + version: 1, + blueprint: { + view: [ + { + type: "TEXT_WIDGET", + position: { left: 1, top: 1 }, + size: { + rows: 1 * GRID_DENSITY_MIGRATION_V1, + cols: 10 * GRID_DENSITY_MIGRATION_V1, + }, + props: { + text: "Modal Title", + fontSize: "HEADING1", + version: 1, + }, + }, + ], + }, + }, + }, + ], + }, + }, + [WidgetTypes.TARO_IMAGE_WIDGET]: { + widgetName: "m_image", + rows: 6 * GRID_DENSITY_MIGRATION_V1, + columns: 8 * GRID_DENSITY_MIGRATION_V1, + src: "https://img.yzcdn.cn/vant/cat.jpeg", + version: 1, + }, + [WidgetTypes.TARO_BUTTON_WIDGET]: { + widgetName: "m_button", + rows: 1 * GRID_DENSITY_MIGRATION_V1, + columns: 6 * GRID_DENSITY_MIGRATION_V1, + version: 1, + rounded: true, + text: "好的", + }, + [WidgetTypes.TARO_CELL_WIDGET]: { + widgetName: "m_cell", + rows: 1 * GRID_DENSITY_MIGRATION_V1, + columns: 4 * GRID_DENSITY_MIGRATION_V1, + version: 1, + }, + [WidgetTypes.TARO_HTML_WIDGET]: { + widgetName: "m_html", + rows: 6 * GRID_DENSITY_MIGRATION_V1, + columns: 8 * GRID_DENSITY_MIGRATION_V1, + content: "五彩斑斓的黑", + version: 1, + }, + [WidgetTypes.TARO_SIMPLE_FORM_WIDGET]: { + widgetName: "m_form", + rows: 1 * GRID_DENSITY_MIGRATION_V1, + columns: 4 * GRID_DENSITY_MIGRATION_V1, + version: 1, + }, + [WidgetTypes.TARO_KV_WIDGET]: { + widgetName: "m_kv", + rows: 1 * GRID_DENSITY_MIGRATION_V1, + columns: 4 * GRID_DENSITY_MIGRATION_V1, + version: 1, + }, + [WidgetTypes.TARO_TABS_WIDGET]: { + widgetName: "m_tabs", + rows: 1 * GRID_DENSITY_MIGRATION_V1, + columns: 4 * GRID_DENSITY_MIGRATION_V1, + version: 1, + }, }, configVersion: 1, }; diff --git a/app/client/src/mockResponses/WidgetSidebarResponse.tsx b/app/client/src/mockResponses/WidgetSidebarResponse.tsx index 622f226c48..cdc84ac61c 100644 --- a/app/client/src/mockResponses/WidgetSidebarResponse.tsx +++ b/app/client/src/mockResponses/WidgetSidebarResponse.tsx @@ -135,6 +135,84 @@ const WidgetSidebarResponse: WidgetCardProps[] = [ widgetCardName: "复杂表单", key: generateReactKey(), }, + // { + // type: "TARO_PICKER_WIDGET", + // widgetCardName: "Picker", + // key: generateReactKey(), + // isMobile: true, + // }, + { + type: "TARO_SWIPER_WIDGET", + widgetCardName: "轮播", + key: generateReactKey(), + isMobile: true, + }, + { + type: "TARO_GRID_WIDGET", + widgetCardName: "网格内容", + key: generateReactKey(), + isMobile: true, + }, + { + type: "TARO_TEXT_WIDGET", + widgetCardName: "文本", + key: generateReactKey(), + isMobile: true, + }, + { + type: "TARO_LIST_WIDGET", + widgetCardName: "列表", + key: generateReactKey(), + isMobile: true, + }, + { + type: "TARO_POPUP_WIDGET", + widgetCardName: "底部弹窗", + key: generateReactKey(), + isMobile: true, + }, + { + type: "TARO_IMAGE_WIDGET", + widgetCardName: "图片", + key: generateReactKey(), + isMobile: true, + }, + { + type: "TARO_BUTTON_WIDGET", + widgetCardName: "按钮", + key: generateReactKey(), + isMobile: true, + }, + { + type: "TARO_CELL_WIDGET", + widgetCardName: "单元格", + key: generateReactKey(), + isMobile: true, + }, + { + type: "TARO_HTML_WIDGET", + widgetCardName: "富文本", + key: generateReactKey(), + isMobile: true, + }, + { + type: "TARO_SIMPLE_FORM_WIDGET", + widgetCardName: "快速表单", + key: generateReactKey(), + isMobile: true, + }, + { + type: "TARO_KV_WIDGET", + widgetCardName: "键值对", + key: generateReactKey(), + isMobile: true, + }, + { + type: "TARO_TABS_WIDGET", + widgetCardName: "标签页", + key: generateReactKey(), + isMobile: true, + }, ]; export default WidgetSidebarResponse; diff --git a/app/client/src/pages/Applications/index.tsx b/app/client/src/pages/Applications/index.tsx index 5617e4225d..d8d1ebe6b6 100644 --- a/app/client/src/pages/Applications/index.tsx +++ b/app/client/src/pages/Applications/index.tsx @@ -255,6 +255,27 @@ const OrgShareUsers = styled.div` display: flex; align-items: center; `; +const AddIcon = styled(Icon)` + position: absolute; + top: ${(props) => (props.isMobile ? "12" : "10")}px; + left: 50%; + margin-left: -4.5px; + + & svg { + width: 9px; + height: 9px; + } +`; +const AddTypeIcon = styled(Icon)` + & svg { + width: 39px; + height: 39px; + } +`; + +const IconGroup = styled.div` + position: relative; +`; function Item(props: { label: string; @@ -613,7 +634,11 @@ function ApplicationsSection(props: any) { ); } - const createNewApplication = (applicationName: string, orgId: string) => { + const createNewApplication = ( + applicationName: string, + orgId: string, + isMobile: boolean, + ) => { const color = getRandomPaletteColor(theme.colors.appCardColors); const icon = AppIconCollection[Math.floor(Math.random() * AppIconCollection.length)]; @@ -625,10 +650,58 @@ function ApplicationsSection(props: any) { orgId, icon, color, + isMobile, }, }); }; + const CreateApp = ({ isMobile, orgId, applications }: any) => { + return ( + + { + if ( + Object.entries(creatingApplicationMap).length === 0 || + (creatingApplicationMap && !creatingApplicationMap[orgId]) + ) { + createNewApplication( + getNextEntityName( + "未命名应用 ", + applications.map((el: any) => el.name), + ), + orgId, + isMobile, + ); + } + }} + > + {creatingApplicationMap && creatingApplicationMap[orgId] ? ( + + ) : ( + <> + + + + + + 新建{isMobile ? "移动" : "桌面"}应用 + + + )} + + + ); + }; + let updatedOrgs; if (!isFetchingApplications) { updatedOrgs = userOrgs; @@ -820,44 +893,17 @@ function ApplicationsSection(props: any) { PERMISSION_TYPE.CREATE_APPLICATION, ) && !isFetchingApplications && ( - - { - if ( - Object.entries(creatingApplicationMap).length === 0 || - (creatingApplicationMap && - !creatingApplicationMap[organization.id]) - ) { - createNewApplication( - getNextEntityName( - "未命名应用 ", - applications.map((el: any) => el.name), - ), - organization.id, - ); - } - }} - > - {creatingApplicationMap && - creatingApplicationMap[organization.id] ? ( - - ) : ( - <> - - - 新建应用 - - - )} - - + <> + + + )} {applications.map((application: any) => { return ( diff --git a/app/client/src/pages/Editor/Explorer/Widgets/WidgetEntity.tsx b/app/client/src/pages/Editor/Explorer/Widgets/WidgetEntity.tsx index a94ebaf13b..922146cf56 100644 --- a/app/client/src/pages/Editor/Explorer/Widgets/WidgetEntity.tsx +++ b/app/client/src/pages/Editor/Explorer/Widgets/WidgetEntity.tsx @@ -113,7 +113,9 @@ export const WidgetEntity = memo((props: WidgetEntityProps) => { * so we track the immediate modal parent for the widget */ const parentModalIdForChildren = useMemo(() => { - return widgetType === "MODAL_WIDGET" ? widgetId : parentModalId; + return widgetType === "MODAL_WIDGET" || widgetType === "TARO_POPUP_WIDGET" + ? widgetId + : parentModalId; }, [widgetType, widgetId, parentModalId]); if (UNREGISTERED_WIDGETS.indexOf(props.widgetType) > -1) return null; diff --git a/app/client/src/pages/Editor/Explorer/Widgets/useNavigateToWidget.ts b/app/client/src/pages/Editor/Explorer/Widgets/useNavigateToWidget.ts index 6695a44e0c..2fca87a38a 100644 --- a/app/client/src/pages/Editor/Explorer/Widgets/useNavigateToWidget.ts +++ b/app/client/src/pages/Editor/Explorer/Widgets/useNavigateToWidget.ts @@ -33,7 +33,10 @@ export const useNavigateToWidget = () => { pageId: string, parentModalId?: string, ) => { - if (widgetType === WidgetTypes.MODAL_WIDGET) { + if ( + widgetType === WidgetTypes.MODAL_WIDGET || + widgetType === WidgetTypes.TARO_POPUP_WIDGET + ) { dispatch(showModal(widgetId)); return; } diff --git a/app/client/src/pages/Editor/MainContainerLayoutControl.tsx b/app/client/src/pages/Editor/MainContainerLayoutControl.tsx index 417ef2a282..445219b0bf 100644 --- a/app/client/src/pages/Editor/MainContainerLayoutControl.tsx +++ b/app/client/src/pages/Editor/MainContainerLayoutControl.tsx @@ -42,11 +42,11 @@ const AppsmithLayouts: AppsmithLayoutConfigOption[] = [ type: "TABLET", icon: "tablet", }, - { - name: "手机宽度", - type: "MOBILE", - icon: "mobile", - }, + // { + // name: "手机宽度", + // type: "MOBILE", + // icon: "mobile", + // }, { name: "自适应宽度", type: "FLUID", @@ -71,9 +71,14 @@ const LayoutControlWrapper = styled.div` } `; +const EmptyBlock = styled.div` + height: 30px; +`; + export function MainContainerLayoutControl() { const appId = useSelector(getCurrentApplicationId); const appLayout = useSelector(getCurrentApplicationLayout); + const isMobile = appLayout?.type === "MOBILE_FLUID"; const layoutOptions = AppsmithLayouts.map((each) => { return { ...each, @@ -89,8 +94,8 @@ export function MainContainerLayoutControl() { const selectedLayout = appLayout ? layoutOptions.find((each) => each.type === appLayout.type) : layoutOptions[0]; - const dispatch = useDispatch(); + const dispatch = useDispatch(); const updateAppLayout = (layoutConfig: AppLayoutConfig) => { const { type } = layoutConfig; dispatch( @@ -101,6 +106,10 @@ export function MainContainerLayoutControl() { }), ); }; + + if (isMobile) { + return ; + } return (
diff --git a/app/client/src/pages/Editor/PropertyPane/ConnectDataCTA.tsx b/app/client/src/pages/Editor/PropertyPane/ConnectDataCTA.tsx index 7ad9e9056c..a490b43fa5 100644 --- a/app/client/src/pages/Editor/PropertyPane/ConnectDataCTA.tsx +++ b/app/client/src/pages/Editor/PropertyPane/ConnectDataCTA.tsx @@ -55,6 +55,7 @@ export const excludeList = [ WidgetTypes.TABS_WIDGET, WidgetTypes.FORM_WIDGET, WidgetTypes.MODAL_WIDGET, + WidgetTypes.TARO_POPUP_WIDGET, WidgetTypes.DIVIDER_WIDGET, WidgetTypes.FILE_PICKER_WIDGET, WidgetTypes.BUTTON_WIDGET, diff --git a/app/client/src/reducers/entityReducers/pageListReducer.tsx b/app/client/src/reducers/entityReducers/pageListReducer.tsx index 2a03b01df5..8fe1ff8e61 100644 --- a/app/client/src/reducers/entityReducers/pageListReducer.tsx +++ b/app/client/src/reducers/entityReducers/pageListReducer.tsx @@ -146,7 +146,8 @@ export type SupportedLayouts = | "TABLET_LARGE" | "TABLET" | "MOBILE" - | "FLUID"; + | "FLUID" + | "MOBILE_FLUID"; export interface AppLayoutConfig { type: SupportedLayouts; } diff --git a/app/client/src/reducers/entityReducers/widgetConfigReducer.tsx b/app/client/src/reducers/entityReducers/widgetConfigReducer.tsx index 4bb31856e6..639334cb1f 100644 --- a/app/client/src/reducers/entityReducers/widgetConfigReducer.tsx +++ b/app/client/src/reducers/entityReducers/widgetConfigReducer.tsx @@ -35,6 +35,19 @@ import { RateWidgetProps } from "widgets/RateWidget"; import { IframeWidgetProps } from "widgets/IframeWidget"; import { MenuButtonWidgetProps } from "widgets/MenuButtonWidget"; import { FormilyWidgetProps } from "widgets/FormilyWidget"; +import { PickerWidgetProps } from "widgets/taro/PickerWidget"; +import { SwiperWidgetProps } from "widgets/taro/SwiperWidget"; +import { GridWidgetProps } from "widgets/taro/GridWidget"; +import { MTextWidgetProps } from "widgets/taro/TextWidget"; +import { MListWidgetProps } from "widgets/taro/ListWidget"; +import { MPopupWidgetProps } from "widgets/taro/PopupWidget"; +import { MImageWidgetProps } from "widgets/taro/ImageWidget"; +import { MButtonWidgetProps } from "widgets/taro/ButtonWidget"; +import { MCellWidgetProps } from "widgets/taro/CellWidget"; +import { MHtmlWidgetProps } from "widgets/taro/HtmlWidget"; +import { MSimpleFormWidgetProps } from "widgets/taro/SimpleFormWidget"; +import { MKVWidgetProps } from "widgets/taro/KVWidget"; +import { MTabsWidgetProps } from "widgets/taro/TabsWidget"; const initialState: WidgetConfigReducerState = WidgetConfigResponse; @@ -94,6 +107,20 @@ export interface WidgetConfigReducerState { IFRAME_WIDGET: Partial & WidgetConfigProps; MENU_BUTTON_WIDGET: Partial & WidgetConfigProps; FORMILY_WIDGET: Partial & WidgetConfigProps; + TARO_PICKER_WIDGET: Partial & WidgetConfigProps; + TARO_SWIPER_WIDGET: Partial & WidgetConfigProps; + TARO_GRID_WIDGET: Partial & WidgetConfigProps; + TARO_TEXT_WIDGET: Partial & WidgetConfigProps; + TARO_LIST_WIDGET: Partial & WidgetConfigProps; + TARO_POPUP_WIDGET: Partial & WidgetConfigProps; + TARO_IMAGE_WIDGET: Partial & WidgetConfigProps; + TARO_BUTTON_WIDGET: Partial & WidgetConfigProps; + TARO_CELL_WIDGET: Partial & WidgetConfigProps; + TARO_HTML_WIDGET: Partial & WidgetConfigProps; + TARO_SIMPLE_FORM_WIDGET: Partial & + WidgetConfigProps; + TARO_KV_WIDGET: Partial & WidgetConfigProps; + TARO_TABS_WIDGET: Partial & WidgetConfigProps; }; configVersion: number; } diff --git a/app/client/src/sagas/ApplicationSagas.tsx b/app/client/src/sagas/ApplicationSagas.tsx index 68abaa8122..ff1da37309 100644 --- a/app/client/src/sagas/ApplicationSagas.tsx +++ b/app/client/src/sagas/ApplicationSagas.tsx @@ -63,6 +63,7 @@ import { deleteRecentAppEntities } from "utils/storage"; import { reconnectWebsocket as reconnectWebsocketAction } from "actions/websocketActions"; import { getCurrentOrg } from "selectors/organizationSelectors"; import { Org } from "constants/orgConstants"; +import { AppLayoutConfig } from "reducers/entityReducers/pageListReducer"; const getDefaultPageId = ( pages?: ApplicationPagePayload[], @@ -392,12 +393,20 @@ export function* createApplicationSaga( applicationName: string; icon: AppIconName; color: AppColorCode; + isMobile: boolean; orgId: string; resolve: any; reject: any; }>, ) { - const { applicationName, color, icon, orgId, reject } = action.payload; + const { + applicationName, + color, + icon, + orgId, + reject, + isMobile, + } = action.payload; try { const userOrgs = yield select(getUserApplicationsOrgsList); const existingOrgs = userOrgs.filter( @@ -423,11 +432,16 @@ export function* createApplicationSaga( } else { yield put(resetCurrentApplication()); + const layout: AppLayoutConfig = { + type: isMobile ? "MOBILE_FLUID" : "DESKTOP", + }; const request: CreateApplicationRequest = { name: applicationName, icon: icon, color: color, orgId, + unpublishedAppLayout: layout, + publishedAppLayout: layout, }; const response: CreateApplicationResponse = yield call( ApplicationApi.createApplication, @@ -441,6 +455,7 @@ export function* createApplicationSaga( }; AnalyticsUtil.logEvent("CREATE_APP", { appName: application.name, + isMobile, }); // This sets ui.pageWidgets = {} to ensure that // widgets are cleaned up from state before @@ -458,6 +473,7 @@ export function* createApplicationSaga( const pageURL = getGenerateTemplateURL( application.id, application.defaultPageId, + isMobile, ); history.push(pageURL); diff --git a/app/client/src/sagas/ModalSagas.ts b/app/client/src/sagas/ModalSagas.ts index d8d7489f91..e34e267fb5 100644 --- a/app/client/src/sagas/ModalSagas.ts +++ b/app/client/src/sagas/ModalSagas.ts @@ -27,6 +27,7 @@ import { getWidgetsMeta, getWidgetIdsByType, getWidgetMetaProps, + getWidgetIdsByTypes, } from "sagas/selectors"; import { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReducer"; import { updateWidgetMetaProperty } from "actions/metaActions"; @@ -34,21 +35,23 @@ import { focusWidget } from "actions/widgetActions"; import log from "loglevel"; import { flatten } from "lodash"; import AppsmithConsole from "utils/AppsmithConsole"; +import { isMobileLayout } from "selectors/editorSelectors"; export function* createModalSaga(action: ReduxAction<{ modalName: string }>) { try { + const isMobile: boolean = yield select(isMobileLayout); const modalWidgetId = generateReactKey(); const props: WidgetAddChild = { widgetId: MAIN_CONTAINER_WIDGET_ID, widgetName: action.payload.modalName, - type: WidgetTypes.MODAL_WIDGET, + type: isMobile ? WidgetTypes.TARO_POPUP_WIDGET : WidgetTypes.MODAL_WIDGET, newWidgetId: modalWidgetId, - parentRowSpace: 1, + parentRowSpace: isMobile ? 10 : 1, parentColumnSpace: 1, leftColumn: 0, topRow: 0, columns: 0, - rows: 0, + rows: isMobile ? 40 : 0, tabId: "", }; yield put({ @@ -98,7 +101,10 @@ export function* showModalByNameSaga( export function* showIfModalSaga( action: ReduxAction<{ widgetId: string; type: string }>, ) { - if (action.payload.type === "MODAL_WIDGET") { + if ( + action.payload.type === "MODAL_WIDGET" || + action.payload.type === WidgetTypes.TARO_POPUP_WIDGET + ) { yield put({ type: ReduxActionTypes.SHOW_MODAL, payload: { modalId: action.payload.widgetId }, @@ -160,10 +166,10 @@ export function* closeModalSaga( const metaProps: Record = yield select(getWidgetsMeta); // Get widgetIds of all widgets of type MODAL_WIDGET - const modalWidgetIds: string[] = yield select( - getWidgetIdsByType, + const modalWidgetIds: string[] = yield select(getWidgetIdsByTypes, [ WidgetTypes.MODAL_WIDGET, - ); + WidgetTypes.TARO_POPUP_WIDGET, + ]); // Loop through all modal widgetIds modalWidgetIds.forEach((widgetId: string) => { diff --git a/app/client/src/sagas/PageSagas.tsx b/app/client/src/sagas/PageSagas.tsx index 1bd4776e71..7d236d377d 100644 --- a/app/client/src/sagas/PageSagas.tsx +++ b/app/client/src/sagas/PageSagas.tsx @@ -71,6 +71,7 @@ import { getCurrentLayoutId, getCurrentPageId, getCurrentPageName, + isMobileLayout, } from "selectors/editorSelectors"; import { fetchActionsForPage, @@ -486,6 +487,7 @@ export function* createPageSaga( const request: CreatePageRequest = createPageAction.payload; const response: FetchPageResponse = yield call(PageApi.createPage, request); const isValidResponse: boolean = yield validateResponse(response); + const isMobile: boolean = yield select(isMobileLayout); if (isValidResponse) { yield put({ type: ReduxActionTypes.CREATE_PAGE_SUCCESS, @@ -508,6 +510,7 @@ export function* createPageSaga( getGenerateTemplateURL( createPageAction.payload.applicationId, response.data.id, + isMobile, ), ); } diff --git a/app/client/src/sagas/selectors.tsx b/app/client/src/sagas/selectors.tsx index ac3a4d57ee..4a2b222c94 100644 --- a/app/client/src/sagas/selectors.tsx +++ b/app/client/src/sagas/selectors.tsx @@ -29,6 +29,12 @@ export const getWidgetIdsByType = (state: AppState, type: WidgetType) => { .map((widget: FlattenedWidgetProps) => widget.widgetId); }; +export const getWidgetIdsByTypes = (state: AppState, types: WidgetType[]) => { + return Object.values(state.entities.canvasWidgets) + .filter((widget: FlattenedWidgetProps) => _.includes(types, widget.type)) + .map((widget: FlattenedWidgetProps) => widget.widgetId); +}; + export const getWidgetOptionsTree = createSelector(getWidgets, (widgets) => Object.values(widgets) .filter((w) => w.type !== "CANVAS_WIDGET" && w.type !== "BUTTON_WIDGET") diff --git a/app/client/src/selectors/editorSelectors.tsx b/app/client/src/selectors/editorSelectors.tsx index b48de358df..a0d2962db5 100644 --- a/app/client/src/selectors/editorSelectors.tsx +++ b/app/client/src/selectors/editorSelectors.tsx @@ -21,6 +21,7 @@ import _ from "lodash"; import { ContainerWidgetProps } from "widgets/ContainerWidget"; import { DataTreeWidget, ENTITY_TYPE } from "entities/DataTree/dataTreeFactory"; import { getActions } from "selectors/entitiesSelector"; +import { AppLayoutConfig } from "reducers/entityReducers/pageListReducer"; import { getCanvasWidgets } from "./entitiesSelector"; import { WidgetTypes } from "../constants/WidgetConstants"; @@ -109,6 +110,9 @@ export const getViewModePageList = createSelector( export const getCurrentApplicationLayout = (state: AppState) => state.ui.applications.currentApplication?.appLayout; +export const isMobileLayout = (state: AppState) => + state.ui.applications.currentApplication?.appLayout?.type === "MOBILE_FLUID"; + export const getCurrentPageName = createSelector( getPageListState, (pageList: PageListReduxState) => @@ -119,11 +123,15 @@ export const getCurrentPageName = createSelector( export const getWidgetCards = createSelector( getWidgetSideBar, getWidgetConfigs, + isMobileLayout, ( widgetCards: WidgetSidebarReduxState, widgetConfigs: WidgetConfigReducerState, + isMobile: boolean, ) => { - const cards = widgetCards.cards; + const cards = widgetCards.cards.filter((c) => + isMobile ? c.isMobile : !c.isMobile, + ); return cards .map((widget: WidgetCardProps) => { const { diff --git a/app/client/src/selectors/entitiesSelector.ts b/app/client/src/selectors/entitiesSelector.ts index 4ac3d1e26c..777df5063f 100644 --- a/app/client/src/selectors/entitiesSelector.ts +++ b/app/client/src/selectors/entitiesSelector.ts @@ -367,7 +367,10 @@ const getParentModalId = (widget: any, pageWidgets: Record) => { let { parentId } = widget; let parentWidget = pageWidgets[parentId]; while (parentId && parentId !== MAIN_CONTAINER_WIDGET_ID) { - if (parentWidget?.type === "MODAL_WIDGET") { + if ( + parentWidget?.type === "MODAL_WIDGET" || + parentWidget?.type === "TARO_POPUP_WIDGET" + ) { parentModalId = parentId; break; } diff --git a/app/client/src/selectors/widgetSelectors.ts b/app/client/src/selectors/widgetSelectors.ts index 1e38e687a8..4d9e5ba63b 100644 --- a/app/client/src/selectors/widgetSelectors.ts +++ b/app/client/src/selectors/widgetSelectors.ts @@ -4,6 +4,7 @@ import { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReduc import { WidgetTypes } from "constants/WidgetConstants"; import { getExistingWidgetNames, getWidgetNamePrefix } from "sagas/selectors"; import { getNextEntityName } from "utils/AppsmithUtils"; +import { isMobileLayout } from "selectors/editorSelectors"; const getCanvasWidgets = (state: AppState) => state.entities.canvasWidgets; export const getModalDropdownList = createSelector( @@ -11,7 +12,8 @@ export const getModalDropdownList = createSelector( (widgets) => { const modalWidgets = Object.values(widgets).filter( (widget: FlattenedWidgetProps) => - widget.type === WidgetTypes.MODAL_WIDGET, + widget.type === WidgetTypes.MODAL_WIDGET || + widget.type === WidgetTypes.TARO_POPUP_WIDGET, ); if (modalWidgets.length === 0) return undefined; @@ -23,8 +25,12 @@ export const getModalDropdownList = createSelector( }, ); -const getModalNamePrefix = (state: AppState) => - getWidgetNamePrefix(state, WidgetTypes.MODAL_WIDGET); +const getModalNamePrefix = (state: AppState) => { + const type = isMobileLayout(state) + ? WidgetTypes.TARO_POPUP_WIDGET + : WidgetTypes.MODAL_WIDGET; + return getWidgetNamePrefix(state, type); +}; export const getNextModalName = createSelector( getExistingWidgetNames, diff --git a/app/client/src/utils/WidgetPropsUtils.tsx b/app/client/src/utils/WidgetPropsUtils.tsx index 978f06ccf9..6e0540f06f 100644 --- a/app/client/src/utils/WidgetPropsUtils.tsx +++ b/app/client/src/utils/WidgetPropsUtils.tsx @@ -1267,7 +1267,11 @@ export const generateWidgetProps = ( const others = {}; const props: ContainerWidgetProps = { - isVisible: WidgetTypes.MODAL_WIDGET === type ? undefined : true, + isVisible: + WidgetTypes.MODAL_WIDGET === type || + WidgetTypes.TARO_POPUP_WIDGET === type + ? undefined + : true, ...widgetConfig, type, widgetName, diff --git a/app/client/src/utils/WidgetRegistry.tsx b/app/client/src/utils/WidgetRegistry.tsx index 9742d29489..d769c7cd75 100644 --- a/app/client/src/utils/WidgetRegistry.tsx +++ b/app/client/src/utils/WidgetRegistry.tsx @@ -127,6 +127,58 @@ import FormilyWidget, { FormilyWidgetProps, ProfiledFormilyWidget, } from "widgets/FormilyWidget"; +import PickerWidget, { + PickerWidgetProps, + ProfiledPickerWidget, +} from "widgets/taro/PickerWidget"; +import SwiperWidget, { + SwiperWidgetProps, + ProfiledSwiperWidget, +} from "widgets/taro/SwiperWidget"; +import GridWidget, { + GridWidgetProps, + ProfiledGridWidget, +} from "widgets/taro/GridWidget"; +import MTextWidget, { + MTextWidgetProps, + MProfiledTextWidget, +} from "widgets/taro/TextWidget"; +import MListWidget, { + MListWidgetProps, + MProfiledListWidget, +} from "widgets/taro/ListWidget"; +import MPopupWidget, { + MPopupWidgetProps, + MProfiledPopupWidget, +} from "widgets/taro/PopupWidget"; +import MImageWidget, { + MImageWidgetProps, + MProfiledImageWidget, +} from "widgets/taro/ImageWidget"; +import MButtonWidget, { + MButtonWidgetProps, + MProfiledButtonWidget, +} from "widgets/taro/ButtonWidget"; +import MCellWidget, { + MCellWidgetProps, + MProfiledCellWidget, +} from "widgets/taro/CellWidget"; +import MHtmlWidget, { + MHtmlWidgetProps, + MProfiledHtmlWidget, +} from "widgets/taro/HtmlWidget"; +import MSimpleFormWidget, { + MSimpleFormWidgetProps, + MProfiledSimpleFormWidget, +} from "widgets/taro/SimpleFormWidget"; +import MKVWidget, { + MKVWidgetProps, + MProfiledKVWidget, +} from "widgets/taro/KVWidget"; +import MTabsWidget, { + MTabsWidgetProps, + MProfiledTabsWidget, +} from "widgets/taro/TabsWidget"; export default class WidgetBuilderRegistry { static registerWidgetBuilders() { @@ -555,5 +607,174 @@ export default class WidgetBuilderRegistry { FormilyWidget.getMetaPropertiesMap(), FormilyWidget.getPropertyPaneConfig(), ); + + WidgetFactory.registerWidgetBuilder( + WidgetTypes.TARO_PICKER_WIDGET, + { + buildWidget(widgetData: PickerWidgetProps): JSX.Element { + return ; + }, + }, + PickerWidget.getDerivedPropertiesMap(), + PickerWidget.getDefaultPropertiesMap(), + PickerWidget.getMetaPropertiesMap(), + PickerWidget.getPropertyPaneConfig(), + ); + + WidgetFactory.registerWidgetBuilder( + WidgetTypes.TARO_SWIPER_WIDGET, + { + buildWidget(widgetData: SwiperWidgetProps): JSX.Element { + return ; + }, + }, + SwiperWidget.getDerivedPropertiesMap(), + SwiperWidget.getDefaultPropertiesMap(), + SwiperWidget.getMetaPropertiesMap(), + SwiperWidget.getPropertyPaneConfig(), + ); + + WidgetFactory.registerWidgetBuilder( + WidgetTypes.TARO_GRID_WIDGET, + { + buildWidget(widgetData: GridWidgetProps): JSX.Element { + return ; + }, + }, + GridWidget.getDerivedPropertiesMap(), + GridWidget.getDefaultPropertiesMap(), + GridWidget.getMetaPropertiesMap(), + GridWidget.getPropertyPaneConfig(), + ); + + WidgetFactory.registerWidgetBuilder( + WidgetTypes.TARO_TEXT_WIDGET, + { + buildWidget(widgetData: MTextWidgetProps): JSX.Element { + return ; + }, + }, + MTextWidget.getDerivedPropertiesMap(), + MTextWidget.getDefaultPropertiesMap(), + MTextWidget.getMetaPropertiesMap(), + MTextWidget.getPropertyPaneConfig(), + ); + + WidgetFactory.registerWidgetBuilder( + WidgetTypes.TARO_LIST_WIDGET, + { + buildWidget(widgetData: MListWidgetProps): JSX.Element { + return ; + }, + }, + MListWidget.getDerivedPropertiesMap(), + MListWidget.getDefaultPropertiesMap(), + MListWidget.getMetaPropertiesMap(), + MListWidget.getPropertyPaneConfig(), + ); + + WidgetFactory.registerWidgetBuilder( + WidgetTypes.TARO_POPUP_WIDGET, + { + buildWidget(widgetData: MPopupWidgetProps): JSX.Element { + return ; + }, + }, + MPopupWidget.getDerivedPropertiesMap(), + MPopupWidget.getDefaultPropertiesMap(), + MPopupWidget.getMetaPropertiesMap(), + MPopupWidget.getPropertyPaneConfig(), + ); + + WidgetFactory.registerWidgetBuilder( + WidgetTypes.TARO_IMAGE_WIDGET, + { + buildWidget(widgetData: MImageWidgetProps): JSX.Element { + return ; + }, + }, + MImageWidget.getDerivedPropertiesMap(), + MImageWidget.getDefaultPropertiesMap(), + MImageWidget.getMetaPropertiesMap(), + MImageWidget.getPropertyPaneConfig(), + ); + + WidgetFactory.registerWidgetBuilder( + WidgetTypes.TARO_BUTTON_WIDGET, + { + buildWidget(widgetData: MButtonWidgetProps): JSX.Element { + return ; + }, + }, + MButtonWidget.getDerivedPropertiesMap(), + MButtonWidget.getDefaultPropertiesMap(), + MButtonWidget.getMetaPropertiesMap(), + MButtonWidget.getPropertyPaneConfig(), + ); + + WidgetFactory.registerWidgetBuilder( + WidgetTypes.TARO_CELL_WIDGET, + { + buildWidget(widgetData: MCellWidgetProps): JSX.Element { + return ; + }, + }, + MCellWidget.getDerivedPropertiesMap(), + MCellWidget.getDefaultPropertiesMap(), + MCellWidget.getMetaPropertiesMap(), + MCellWidget.getPropertyPaneConfig(), + ); + + WidgetFactory.registerWidgetBuilder( + WidgetTypes.TARO_HTML_WIDGET, + { + buildWidget(widgetData: MHtmlWidgetProps): JSX.Element { + return ; + }, + }, + MHtmlWidget.getDerivedPropertiesMap(), + MHtmlWidget.getDefaultPropertiesMap(), + MHtmlWidget.getMetaPropertiesMap(), + MHtmlWidget.getPropertyPaneConfig(), + ); + + WidgetFactory.registerWidgetBuilder( + WidgetTypes.TARO_SIMPLE_FORM_WIDGET, + { + buildWidget(widgetData: MSimpleFormWidgetProps): JSX.Element { + return ; + }, + }, + MSimpleFormWidget.getDerivedPropertiesMap(), + MSimpleFormWidget.getDefaultPropertiesMap(), + MSimpleFormWidget.getMetaPropertiesMap(), + MSimpleFormWidget.getPropertyPaneConfig(), + ); + + WidgetFactory.registerWidgetBuilder( + WidgetTypes.TARO_KV_WIDGET, + { + buildWidget(widgetData: MKVWidgetProps): JSX.Element { + return ; + }, + }, + MKVWidget.getDerivedPropertiesMap(), + MKVWidget.getDefaultPropertiesMap(), + MKVWidget.getMetaPropertiesMap(), + MKVWidget.getPropertyPaneConfig(), + ); + + WidgetFactory.registerWidgetBuilder( + WidgetTypes.TARO_TABS_WIDGET, + { + buildWidget(widgetData: MTabsWidgetProps): JSX.Element { + return ; + }, + }, + MTabsWidget.getDerivedPropertiesMap(), + MTabsWidget.getDefaultPropertiesMap(), + MTabsWidget.getMetaPropertiesMap(), + MTabsWidget.getPropertyPaneConfig(), + ); } } diff --git a/app/client/src/utils/autocomplete/EntityDefinitions.ts b/app/client/src/utils/autocomplete/EntityDefinitions.ts index cc7ba88d01..63abe89de0 100644 --- a/app/client/src/utils/autocomplete/EntityDefinitions.ts +++ b/app/client/src/utils/autocomplete/EntityDefinitions.ts @@ -293,6 +293,59 @@ export const entityDefinitions = { isVisible: isVisible, formData: "any", }, + TARO_PICKER_WIDGET: { + "!doc": "Taro 选择器", + "!url": "https://docs.appsmith.com/widget-reference/input", + isVisible: isVisible, + }, + TARO_SWIPER_WIDGET: { + "!doc": "轮播", + "!url": "https://docs.appsmith.com/widget-reference/input", + }, + TARO_GRID_WIDGET: { + "!doc": "网格内容", + "!url": "https://docs.appsmith.com/widget-reference/input", + }, + TARO_TEXT_WIDGET: { + "!doc": "文本", + "!url": "https://docs.appsmith.com/widget-reference/input", + }, + TARO_LIST_WIDGET: { + "!doc": "列表", + "!url": "https://docs.appsmith.com/widget-reference/input", + }, + TARO_POPUP_WIDGET: { + "!doc": "底部弹窗", + "!url": "https://docs.appsmith.com/widget-reference/input", + }, + TARO_IMAGE_WIDGET: { + "!doc": "图片", + "!url": "https://docs.appsmith.com/widget-reference/input", + }, + TARO_BUTTON_WIDGET: { + "!doc": "按钮", + "!url": "https://docs.appsmith.com/widget-reference/input", + }, + TARO_CELL_WIDGET: { + "!doc": "单元格", + "!url": "https://docs.appsmith.com/widget-reference/input", + }, + TARO_HTML_WIDGET: { + "!doc": "富文本", + "!url": "https://docs.appsmith.com/widget-reference/input", + }, + TARO_SIMPLE_FORM_WIDGET: { + "!doc": "快速表单", + "!url": "https://docs.appsmith.com/widget-reference/input", + }, + TARO_KV_WIDGET: { + "!doc": "键值对", + "!url": "https://docs.appsmith.com/widget-reference/input", + }, + TARO_TABS_WIDGET: { + "!doc": "标签页", + "!url": "https://docs.appsmith.com/widget-reference/input", + }, }; export const GLOBAL_DEFS = { diff --git a/app/client/src/utils/autocomplete/dataTreeTypeDefCreator.ts b/app/client/src/utils/autocomplete/dataTreeTypeDefCreator.ts index b36d2251c4..f49dd0d732 100644 --- a/app/client/src/utils/autocomplete/dataTreeTypeDefCreator.ts +++ b/app/client/src/utils/autocomplete/dataTreeTypeDefCreator.ts @@ -52,8 +52,8 @@ export const dataTreeTypeDefCreator = ( subType: "ACTION", }); } else if (isAppsmithEntity(entity)) { - def.appsmith = generateTypeDef(_.omit(entity, "ENTITY_TYPE")); - entityMap.set("appsmith", { + def.global = generateTypeDef(_.omit(entity, "ENTITY_TYPE")); + entityMap.set("global", { type: ENTITY_TYPE.APPSMITH, subType: ENTITY_TYPE.APPSMITH, }); diff --git a/app/client/src/widgets/BaseWidget.tsx b/app/client/src/widgets/BaseWidget.tsx index 137bb91cec..539a2c3d60 100644 --- a/app/client/src/widgets/BaseWidget.tsx +++ b/app/client/src/widgets/BaseWidget.tsx @@ -492,6 +492,7 @@ export interface WidgetCardProps { key?: string; widgetCardName: string; isBeta?: boolean; + isMobile?: boolean; } export const WidgetOperations = { diff --git a/app/client/src/widgets/FormilyWidget.tsx b/app/client/src/widgets/FormilyWidget.tsx index 9bbe0aeacf..eef5b69145 100644 --- a/app/client/src/widgets/FormilyWidget.tsx +++ b/app/client/src/widgets/FormilyWidget.tsx @@ -125,7 +125,6 @@ class FormilyWidget extends BaseWidget { }; getPageView() { - console.log("----widget--props--", this.props); const { title, formType, diff --git a/app/client/src/widgets/taro/ButtonWidget.tsx b/app/client/src/widgets/taro/ButtonWidget.tsx new file mode 100644 index 0000000000..c35fbaedfb --- /dev/null +++ b/app/client/src/widgets/taro/ButtonWidget.tsx @@ -0,0 +1,136 @@ +import React from "react"; +import BaseWidget, { WidgetProps, WidgetState } from "../BaseWidget"; +import { WidgetType } from "constants/WidgetConstants"; +import ButtonComponent from "components/designSystems/taro/ButtonComponent"; +import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; +import { ValidationTypes } from "constants/WidgetValidation"; +import withMeta, { WithMeta } from "../MetaHOC"; + +class MButtonWidget extends BaseWidget { + state = { + isLoading: false, + }; + + static getPropertyPaneConfig() { + return [ + { + sectionName: "属性", + children: [ + { + propertyName: "text", + label: "按钮文字", + controlType: "INPUT_TEXT", + placeholderText: "输入按钮文字", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "color", + label: "按钮颜色", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "rounded", + label: "是否圆角", + controlType: "SWITCH", + isBindProperty: false, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "isVisible", + label: "是否可见", + helpText: "控制按钮显示/隐藏", + controlType: "SWITCH", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "isDisabled", + label: "禁用", + controlType: "SWITCH", + helpText: "禁止按钮交互", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + ], + }, + { + sectionName: "动作", + children: [ + { + helpText: "点击按钮时触发动作", + propertyName: "onClick", + label: "onClick", + controlType: "ACTION_SELECTOR", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: true, + }, + ], + }, + ]; + } + + onButtonClick = () => { + if (this.props.onClick) { + this.setState({ + isLoading: true, + }); + super.executeAction({ + triggerPropertyName: "onClick", + dynamicString: this.props.onClick, + event: { + type: EventType.ON_CLICK, + callback: this.handleActionComplete, + }, + }); + } + }; + + handleActionComplete = () => { + this.setState({ + isLoading: false, + }); + }; + + getPageView() { + return ( + + ); + } + + getWidgetType(): WidgetType { + return "TARO_BUTTON_WIDGET"; + } +} + +export interface MButtonWidgetProps extends WidgetProps, WithMeta { + text?: string; + color?: string; + onClick?: string; + rounded?: boolean; + isDisabled?: boolean; + isVisible?: boolean; +} + +interface ButtonWidgetState extends WidgetState { + isLoading: boolean; +} + +export default MButtonWidget; +export const MProfiledButtonWidget = withMeta(MButtonWidget); diff --git a/app/client/src/widgets/taro/CellWidget.tsx b/app/client/src/widgets/taro/CellWidget.tsx new file mode 100644 index 0000000000..819246d848 --- /dev/null +++ b/app/client/src/widgets/taro/CellWidget.tsx @@ -0,0 +1,136 @@ +import React from "react"; +import BaseWidget, { WidgetProps, WidgetState } from "../BaseWidget"; +import { WidgetType } from "constants/WidgetConstants"; +import ButtonComponent from "components/designSystems/taro/ButtonComponent"; +import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; +import { ValidationTypes } from "constants/WidgetValidation"; +import withMeta, { WithMeta } from "../MetaHOC"; + +class MCellWidget extends BaseWidget { + state = { + isLoading: false, + }; + + static getPropertyPaneConfig() { + return [ + { + sectionName: "属性", + children: [ + { + propertyName: "text", + label: "按钮文字", + controlType: "INPUT_TEXT", + placeholderText: "输入按钮文字", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "color", + label: "按钮颜色", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "rounded", + label: "是否圆角", + controlType: "SWITCH", + isBindProperty: false, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "isVisible", + label: "是否可见", + helpText: "控制按钮显示/隐藏", + controlType: "SWITCH", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "isDisabled", + label: "禁用", + controlType: "SWITCH", + helpText: "禁止按钮交互", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + ], + }, + { + sectionName: "动作", + children: [ + { + helpText: "点击按钮时触发动作", + propertyName: "onClick", + label: "onClick", + controlType: "ACTION_SELECTOR", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: true, + }, + ], + }, + ]; + } + + onButtonClick = () => { + if (this.props.onClick) { + this.setState({ + isLoading: true, + }); + super.executeAction({ + triggerPropertyName: "onClick", + dynamicString: this.props.onClick, + event: { + type: EventType.ON_CLICK, + callback: this.handleActionComplete, + }, + }); + } + }; + + handleActionComplete = () => { + this.setState({ + isLoading: false, + }); + }; + + getPageView() { + return ( + + ); + } + + getWidgetType(): WidgetType { + return "TARO_BUTTON_WIDGET"; + } +} + +export interface MCellWidgetProps extends WidgetProps, WithMeta { + text?: string; + color?: string; + onClick?: string; + rounded?: boolean; + isDisabled?: boolean; + isVisible?: boolean; +} + +interface CellWidgetState extends WidgetState { + isLoading: boolean; +} + +export default MCellWidget; +export const MProfiledCellWidget = withMeta(MCellWidget); diff --git a/app/client/src/widgets/taro/GridWidget.tsx b/app/client/src/widgets/taro/GridWidget.tsx new file mode 100644 index 0000000000..38b1755490 --- /dev/null +++ b/app/client/src/widgets/taro/GridWidget.tsx @@ -0,0 +1,243 @@ +import React from "react"; +import BaseWidget, { WidgetProps, WidgetState } from "../BaseWidget"; +import { WidgetType, WidgetTypes } from "constants/WidgetConstants"; +import GridComponent, { + GridComponentProps, +} from "components/designSystems/taro/GridComponent"; +import { ValidationTypes } from "constants/WidgetValidation"; +import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory"; + +class GridWidget extends BaseWidget { + static getPropertyPaneConfig() { + return [ + { + sectionName: "属性", + children: [ + { + helpText: "数组,通过 {{}} 进行数据绑定", + propertyName: "list", + label: "数据", + controlType: "INPUT_TEXT", + placeholderText: '[{ "url": "", title: "" }]', + inputType: "ARRAY", + isBindProperty: true, + isTriggerProperty: false, + validation: { + type: ValidationTypes.OBJECT_ARRAY, + params: { + default: [], + }, + }, + evaluationSubstitutionType: + EvaluationSubstitutionType.SMART_SUBSTITUTE, + }, + { + propertyName: "gridType", + label: "内容类型", + controlType: "DROP_DOWN", + options: [ + { + label: "图片+标题", + value: "I_N", + }, + { + label: "图片+标题+描述", + value: "I_N_D", + }, + { + label: "图片+标题+描述+按钮", + value: "I_N_D_B", + }, + ], + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "urlKey", + label: "图片字段", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "titleKey", + label: "标题字段", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "descriptionKey", + label: "描述字段", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + dependencies: ["gridType"], + hidden: (props: GridWidgetProps) => { + return props.gridType === "I_N"; + }, + }, + { + propertyName: "asPrice", + label: "描述是价格", + controlType: "SWITCH", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + dependencies: ["gridType"], + hidden: (props: GridWidgetProps) => { + return props.gridType === "I_N"; + }, + }, + { + propertyName: "priceUnit", + label: "价格单位符号", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + dependencies: ["gridType", "asPrice"], + hidden: (props: GridWidgetProps) => { + return props.gridType === "I_N" || !props.asPrice; + }, + }, + { + propertyName: "buttonText", + label: "按钮文本", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + dependencies: ["gridType"], + hidden: (props: GridWidgetProps) => { + return props.gridType !== "I_N_D_B"; + }, + }, + ], + }, + { + sectionName: "样式", + children: [ + { + propertyName: "height", + label: "图片高度", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "cols", + label: "列数", + controlType: "INPUT_TEXT", + placeholderText: "网格显示多少列", + isBindProperty: true, + isTriggerProperty: false, + validation: { + type: ValidationTypes.NUMBER, + params: { min: 2, default: 4 }, + }, + }, + { + propertyName: "gutter", + label: "网格间距", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "bordered", + label: "是否显示边框", + controlType: "SWITCH", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "titleColor", + label: "标题颜色", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "descriptionColor", + label: "描述颜色", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + dependencies: ["gridType"], + hidden: (props: GridWidgetProps) => { + return props.gridType === "I_N"; + }, + }, + { + propertyName: "buttonColor", + label: "按钮颜色", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + dependencies: ["gridType"], + hidden: (props: GridWidgetProps) => { + return props.gridType !== "I_N_D_B"; + }, + }, + ], + }, + ]; + } + + getPageView() { + const { + list, + gridType, + urlKey, + titleKey, + descriptionKey, + asPrice, + priceUnit, + buttonText, + height, + cols, + gutter, + bordered, + titleColor, + descriptionColor, + buttonColor, + } = this.props; + return ( + + ); + } + + getWidgetType(): WidgetType { + return WidgetTypes.TARO_GRID_WIDGET; + } +} + +export interface GridWidgetProps extends WidgetProps, GridComponentProps {} + +export default GridWidget; +export const ProfiledGridWidget = GridWidget; diff --git a/app/client/src/widgets/taro/HtmlWidget.tsx b/app/client/src/widgets/taro/HtmlWidget.tsx new file mode 100644 index 0000000000..c93d4aca62 --- /dev/null +++ b/app/client/src/widgets/taro/HtmlWidget.tsx @@ -0,0 +1,55 @@ +import React from "react"; +import BaseWidget, { WidgetProps, WidgetState } from "../BaseWidget"; +import { ScrollView, RichText } from "@tarojs/components"; +import { WidgetType } from "constants/WidgetConstants"; +import { ValidationTypes } from "constants/WidgetValidation"; +import styled from "styled-components"; + +const Container = styled(ScrollView)` + width: 100%; + height: 100%; + & img { + width: 100%; + } +`; + +class MHtmlWidget extends BaseWidget { + static getPropertyPaneConfig() { + return [ + { + sectionName: "属性", + children: [ + { + propertyName: "content", + label: "HTML内容", + controlType: "INPUT_TEXT", + placeholderText: "输入HTML格式内容", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + ], + }, + ]; + } + + getPageView() { + const { content } = this.props; + return ( + + + + ); + } + + getWidgetType(): WidgetType { + return "TARO_HTML_WIDGET"; + } +} + +export interface MHtmlWidgetProps extends WidgetProps { + content: string; +} + +export default MHtmlWidget; +export const MProfiledHtmlWidget = MHtmlWidget; diff --git a/app/client/src/widgets/taro/ImageWidget.tsx b/app/client/src/widgets/taro/ImageWidget.tsx new file mode 100644 index 0000000000..b4293802f9 --- /dev/null +++ b/app/client/src/widgets/taro/ImageWidget.tsx @@ -0,0 +1,136 @@ +import * as React from "react"; +import BaseWidget, { WidgetProps, WidgetState } from "../BaseWidget"; +import { WidgetType, RenderModes } from "constants/WidgetConstants"; +import ImageComponent from "components/designSystems/taro/ImageComponent"; +import { ValidationTypes } from "constants/WidgetValidation"; +import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; + +class MImageWidget extends BaseWidget { + static getPropertyPaneConfig() { + return [ + { + sectionName: "属性", + children: [ + { + propertyName: "src", + label: "图片地址", + controlType: "INPUT_TEXT", + placeholderText: "输入图片 URL", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.IMAGE_URL }, + }, + { + helpText: "设置图片填充父容器的方式", + propertyName: "mode", + label: "图片填充方式", + controlType: "DROP_DOWN", + defaultValue: "aspectFill", + options: [ + { + label: "封面模式,保持原始比例", + value: "aspectFill", + }, + { + label: "填充模式,不保持原始比例", + value: "scaleToFill", + }, + { + label: "包含模式,保持原始比例", + value: "aspectFit", + }, + ], + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "isCircle", + label: "显示为圆形", + controlType: "SWITCH", + isBindProperty: false, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "radius", + label: "圆角大小(默认单位 px)", + controlType: "INPUT_TEXT", + isBindProperty: false, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + dependencies: ["isCircle"], + hidden: (props: MImageWidgetProps) => { + return !!props.isCircle; + }, + }, + { + helpText: "控制组件显示/隐藏", + propertyName: "isVisible", + label: "是否可见", + controlType: "SWITCH", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + ], + }, + { + sectionName: "动作", + children: [ + { + helpText: "当用户点击图片时触发", + propertyName: "onClick", + label: "onClick", + controlType: "ACTION_SELECTOR", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: true, + }, + ], + }, + ]; + } + + getPageView() { + const { src, onClick, mode, isCircle, radius } = this.props; + return ( + + ); + } + + onImageClick = () => { + if (this.props.onClick) { + super.executeAction({ + triggerPropertyName: "onClick", + dynamicString: this.props.onClick, + event: { + type: EventType.ON_CLICK, + }, + }); + } + }; + + getWidgetType(): WidgetType { + return "TARO_IMAGE_WIDGET"; + } +} + +export type ImageFillMode = "aspectFill" | "scaleToFill" | "aspectFit"; + +export interface MImageWidgetProps extends WidgetProps { + src: string; + mode: ImageFillMode; + isCircle?: boolean; + radius?: string; + onClick?: string; +} + +export default MImageWidget; +export const MProfiledImageWidget = MImageWidget; diff --git a/app/client/src/widgets/taro/KVWidget.tsx b/app/client/src/widgets/taro/KVWidget.tsx new file mode 100644 index 0000000000..79cc49ebad --- /dev/null +++ b/app/client/src/widgets/taro/KVWidget.tsx @@ -0,0 +1,136 @@ +import React from "react"; +import BaseWidget, { WidgetProps, WidgetState } from "../BaseWidget"; +import { WidgetType } from "constants/WidgetConstants"; +import ButtonComponent from "components/designSystems/taro/ButtonComponent"; +import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; +import { ValidationTypes } from "constants/WidgetValidation"; +import withMeta, { WithMeta } from "../MetaHOC"; + +class MKVWidget extends BaseWidget { + state = { + isLoading: false, + }; + + static getPropertyPaneConfig() { + return [ + { + sectionName: "属性", + children: [ + { + propertyName: "text", + label: "按钮文字", + controlType: "INPUT_TEXT", + placeholderText: "输入按钮文字", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "color", + label: "按钮颜色", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "rounded", + label: "是否圆角", + controlType: "SWITCH", + isBindProperty: false, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "isVisible", + label: "是否可见", + helpText: "控制按钮显示/隐藏", + controlType: "SWITCH", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "isDisabled", + label: "禁用", + controlType: "SWITCH", + helpText: "禁止按钮交互", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + ], + }, + { + sectionName: "动作", + children: [ + { + helpText: "点击按钮时触发动作", + propertyName: "onClick", + label: "onClick", + controlType: "ACTION_SELECTOR", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: true, + }, + ], + }, + ]; + } + + onButtonClick = () => { + if (this.props.onClick) { + this.setState({ + isLoading: true, + }); + super.executeAction({ + triggerPropertyName: "onClick", + dynamicString: this.props.onClick, + event: { + type: EventType.ON_CLICK, + callback: this.handleActionComplete, + }, + }); + } + }; + + handleActionComplete = () => { + this.setState({ + isLoading: false, + }); + }; + + getPageView() { + return ( + + ); + } + + getWidgetType(): WidgetType { + return "TARO_BUTTON_WIDGET"; + } +} + +export interface MKVWidgetProps extends WidgetProps, WithMeta { + text?: string; + color?: string; + onClick?: string; + rounded?: boolean; + isDisabled?: boolean; + isVisible?: boolean; +} + +interface KVWidgetState extends WidgetState { + isLoading: boolean; +} + +export default MKVWidget; +export const MProfiledKVWidget = withMeta(MKVWidget); diff --git a/app/client/src/widgets/taro/ListWidget.tsx b/app/client/src/widgets/taro/ListWidget.tsx new file mode 100644 index 0000000000..b39d8af58b --- /dev/null +++ b/app/client/src/widgets/taro/ListWidget.tsx @@ -0,0 +1,220 @@ +import React from "react"; +import BaseWidget, { WidgetProps, WidgetState } from "../BaseWidget"; +import { WidgetType, WidgetTypes } from "constants/WidgetConstants"; +import ListComponent, { + ListComponentProps, +} from "components/designSystems/taro/ListComponent"; +import { ValidationTypes } from "constants/WidgetValidation"; +import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory"; + +class ListWidget extends BaseWidget { + static getPropertyPaneConfig() { + return [ + { + sectionName: "属性", + children: [ + { + helpText: "数组,通过 {{}} 进行数据绑定", + propertyName: "list", + label: "数据", + controlType: "INPUT_TEXT", + placeholderText: '[{ "url": "", name: "" }]', + inputType: "ARRAY", + isBindProperty: true, + isTriggerProperty: false, + validation: { + type: ValidationTypes.OBJECT_ARRAY, + params: { + default: [], + }, + }, + evaluationSubstitutionType: + EvaluationSubstitutionType.SMART_SUBSTITUTE, + }, + { + propertyName: "contentType", + label: "内容类型", + controlType: "DROP_DOWN", + options: [ + { + label: "图片+标题+描述", + value: "I_N_D", + }, + { + label: "图片+标题+描述+价格", + value: "I_N_D_P", + }, + { + label: "图片+标题+描述+价格+按钮", + value: "I_N_D_P_B", + }, + ], + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "urlKey", + label: "图片字段", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "titleKey", + label: "标题字段", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "descriptionKey", + label: "描述字段", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "priceKey", + label: "价格字段", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + dependencies: ["contentType"], + hidden: (props: MListWidgetProps) => { + return props.contentType === "I_N_D"; + }, + }, + { + propertyName: "buttonText", + label: "按钮文本", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + dependencies: ["contentType"], + hidden: (props: MListWidgetProps) => { + return props.contentType !== "I_N_D_P_B"; + }, + }, + ], + }, + { + sectionName: "样式", + children: [ + { + propertyName: "inset", + label: "圆角风格", + controlType: "SWITCH", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "width", + label: "图片宽度", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "height", + label: "图片高度", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "titleColor", + label: "标题颜色", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "descriptionColor", + label: "描述颜色", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "priceColor", + label: "价格颜色", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + dependencies: ["contentType"], + hidden: (props: MListWidgetProps) => { + return props.contentType === "I_N_D"; + }, + }, + { + propertyName: "buttonColor", + label: "按钮颜色", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + dependencies: ["contentType"], + hidden: (props: MListWidgetProps) => { + return props.contentType !== "I_N_D_P_B"; + }, + }, + ], + }, + ]; + } + + getPageView() { + const { + list, + contentType, + urlKey, + titleKey, + descriptionKey, + priceKey, + buttonText, + inset, + width, + height, + titleColor, + descriptionColor, + priceColor, + buttonColor, + } = this.props; + return ( + + ); + } + + getWidgetType(): WidgetType { + return WidgetTypes.TARO_LIST_WIDGET; + } +} + +export interface MListWidgetProps extends WidgetProps, ListComponentProps {} + +export default ListWidget; +export const MProfiledListWidget = ListWidget; diff --git a/app/client/src/widgets/taro/PickerWidget.tsx b/app/client/src/widgets/taro/PickerWidget.tsx new file mode 100644 index 0000000000..4ea918dd6d --- /dev/null +++ b/app/client/src/widgets/taro/PickerWidget.tsx @@ -0,0 +1,82 @@ +import React from "react"; +import BaseWidget, { WidgetProps, WidgetState } from "../BaseWidget"; +import { WidgetType, WidgetTypes } from "constants/WidgetConstants"; +import PickerComponent from "components/designSystems/taro/PickerComponent"; +import { ValidationTypes } from "constants/WidgetValidation"; +import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; +import * as Sentry from "@sentry/react"; +import withMeta, { WithMeta } from "../MetaHOC"; + +class PickerWidget extends BaseWidget { + static getPropertyPaneConfig() { + return [ + { + sectionName: "属性", + children: [ + { + propertyName: "title", + label: "这是什么", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + ], + }, + { + sectionName: "动作", + children: [ + { + propertyName: "onTap", + label: "被点击后执行", + controlType: "ACTION_SELECTOR", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: true, + }, + ], + }, + ]; + } + + onButtonClick = (e: any) => { + e.stopPropagation(); + if (this.props.onTap) { + super.executeAction({ + triggerPropertyName: "onTap", + dynamicString: this.props.onTap, + event: { + type: EventType.ON_CLICK, + }, + }); + } + }; + + static getMetaPropertiesMap(): Record { + return {}; + } + + getPageView() { + const { title } = this.props; + return ( + + ); + } + + getWidgetType(): WidgetType { + return WidgetTypes.TARO_PICKER_WIDGET; + } +} + +export interface PickerWidgetProps extends WidgetProps, WithMeta { + title?: string; + onTap?: string; +} + +export default PickerWidget; +export const ProfiledPickerWidget = Sentry.withProfiler(withMeta(PickerWidget)); diff --git a/app/client/src/widgets/taro/PopupWidget.tsx b/app/client/src/widgets/taro/PopupWidget.tsx new file mode 100644 index 0000000000..91aa13036f --- /dev/null +++ b/app/client/src/widgets/taro/PopupWidget.tsx @@ -0,0 +1,178 @@ +import React, { ReactNode } from "react"; +import { connect } from "react-redux"; +import { ReduxActionTypes } from "constants/ReduxActionConstants"; +import BaseWidget, { WidgetProps, WidgetState } from "../BaseWidget"; +import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; +import WidgetFactory from "utils/WidgetFactory"; +import { ValidationTypes } from "constants/WidgetValidation"; +import ModalComponent from "components/designSystems/taro/PopoverComponent"; +import { + WidgetTypes, + RenderMode, + MAIN_CONTAINER_WIDGET_ID, +} from "constants/WidgetConstants"; +import { generateClassName } from "utils/generators"; +import withMeta, { WithMeta } from "../MetaHOC"; +import { AppState } from "reducers"; +import { getWidget } from "sagas/selectors"; + +export class MPopupWidget extends BaseWidget { + static getPropertyPaneConfig() { + return [ + { + sectionName: "属性", + children: [ + { + propertyName: "height", + label: "弹窗高度(不带单位的数字)", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { + type: ValidationTypes.NUMBER, + params: { min: 200, max: 800 }, + }, + }, + { + propertyName: "canOutsideClickClose", + label: "点击背景关闭", + controlType: "SWITCH", + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "rounded", + label: "圆角风格", + controlType: "SWITCH", + isBindProperty: false, + isTriggerProperty: false, + }, + ], + }, + { + sectionName: "动作", + children: [ + { + helpText: "弹窗关闭后触发", + propertyName: "onClose", + label: "onClose", + controlType: "ACTION_SELECTOR", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: true, + }, + ], + }, + ]; + } + + getModalWidth() { + return this.props.mainContainer.rightColumn; + } + + renderChildWidget = (childWidgetData: WidgetProps): ReactNode => { + childWidgetData.parentId = this.props.widgetId; + childWidgetData.shouldScrollContents = false; + childWidgetData.canExtend = false; + childWidgetData.bottomRow = childWidgetData.bottomRow; + childWidgetData.isVisible = this.props.isVisible; + childWidgetData.containerStyle = "none"; + childWidgetData.minHeight = this.props.height; + childWidgetData.rightColumn = this.getModalWidth(); + return WidgetFactory.createWidget(childWidgetData, this.props.renderMode); + }; + + onModalClose = () => { + if (this.props.onClose) { + super.executeAction({ + triggerPropertyName: "onClose", + dynamicString: this.props.onClose, + event: { + type: EventType.ON_MODAL_CLOSE, + }, + }); + } + }; + + closeModal = () => { + this.props.showPropertyPane(undefined); + this.props.updateWidgetMetaProperty("isVisible", false); + }; + + getChildren(): ReactNode { + if (this.props.children && this.props.children.length > 0) { + const children = this.props.children.filter(Boolean); + return children.length > 0 && children.map(this.renderChildWidget); + } + } + + makeModalComponent(content: ReactNode) { + return ( + + {content} + + ); + } + + getCanvasView() { + let children = this.getChildren(); + children = this.showWidgetName(children, true); + return this.makeModalComponent(children); + } + + getPageView() { + const children = this.getChildren(); + return this.makeModalComponent(children); + } + + getWidgetType() { + return WidgetTypes.TARO_POPUP_WIDGET; + } +} + +export interface MPopupWidgetProps extends WidgetProps, WithMeta { + renderMode: RenderMode; + children?: WidgetProps[]; + canOutsideClickClose?: boolean; + rounded?: boolean; + height?: number; + showPropertyPane: (widgetId?: string) => void; + onClose: string; + mainContainer: WidgetProps; +} + +const mapDispatchToProps = (dispatch: any) => ({ + showPropertyPane: ( + widgetId?: string, + callForDragOrResize?: boolean, + force = false, + ) => { + dispatch({ + type: + widgetId || callForDragOrResize + ? ReduxActionTypes.SHOW_PROPERTY_PANE + : ReduxActionTypes.HIDE_PROPERTY_PANE, + payload: { widgetId, callForDragOrResize, force }, + }); + }, +}); + +const mapStateToProps = (state: AppState) => { + const props = { + mainContainer: getWidget(state, MAIN_CONTAINER_WIDGET_ID), + }; + return props; +}; +export default MPopupWidget; +export const MProfiledPopupWidget = connect( + mapStateToProps, + mapDispatchToProps, +)(withMeta(MPopupWidget)); diff --git a/app/client/src/widgets/taro/SimpleFormWidget.tsx b/app/client/src/widgets/taro/SimpleFormWidget.tsx new file mode 100644 index 0000000000..79831ec8df --- /dev/null +++ b/app/client/src/widgets/taro/SimpleFormWidget.tsx @@ -0,0 +1,139 @@ +import React from "react"; +import BaseWidget, { WidgetProps, WidgetState } from "../BaseWidget"; +import { WidgetType } from "constants/WidgetConstants"; +import ButtonComponent from "components/designSystems/taro/ButtonComponent"; +import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; +import { ValidationTypes } from "constants/WidgetValidation"; +import withMeta, { WithMeta } from "../MetaHOC"; + +class MSimpleFormWidget extends BaseWidget< + MSimpleFormWidgetProps, + SimpleFormWidgetState +> { + state = { + isLoading: false, + }; + + static getPropertyPaneConfig() { + return [ + { + sectionName: "属性", + children: [ + { + propertyName: "text", + label: "按钮文字", + controlType: "INPUT_TEXT", + placeholderText: "输入按钮文字", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "color", + label: "按钮颜色", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "rounded", + label: "是否圆角", + controlType: "SWITCH", + isBindProperty: false, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "isVisible", + label: "是否可见", + helpText: "控制按钮显示/隐藏", + controlType: "SWITCH", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "isDisabled", + label: "禁用", + controlType: "SWITCH", + helpText: "禁止按钮交互", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + ], + }, + { + sectionName: "动作", + children: [ + { + helpText: "点击按钮时触发动作", + propertyName: "onClick", + label: "onClick", + controlType: "ACTION_SELECTOR", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: true, + }, + ], + }, + ]; + } + + onButtonClick = () => { + if (this.props.onClick) { + this.setState({ + isLoading: true, + }); + super.executeAction({ + triggerPropertyName: "onClick", + dynamicString: this.props.onClick, + event: { + type: EventType.ON_CLICK, + callback: this.handleActionComplete, + }, + }); + } + }; + + handleActionComplete = () => { + this.setState({ + isLoading: false, + }); + }; + + getPageView() { + return ( + + ); + } + + getWidgetType(): WidgetType { + return "TARO_BUTTON_WIDGET"; + } +} + +export interface MSimpleFormWidgetProps extends WidgetProps, WithMeta { + text?: string; + color?: string; + onClick?: string; + rounded?: boolean; + isDisabled?: boolean; + isVisible?: boolean; +} + +interface SimpleFormWidgetState extends WidgetState { + isLoading: boolean; +} + +export default MSimpleFormWidget; +export const MProfiledSimpleFormWidget = withMeta(MSimpleFormWidget); diff --git a/app/client/src/widgets/taro/SwiperWidget.tsx b/app/client/src/widgets/taro/SwiperWidget.tsx new file mode 100644 index 0000000000..db0ed4748c --- /dev/null +++ b/app/client/src/widgets/taro/SwiperWidget.tsx @@ -0,0 +1,63 @@ +import React from "react"; +import BaseWidget, { WidgetProps, WidgetState } from "../BaseWidget"; +import { WidgetType, WidgetTypes } from "constants/WidgetConstants"; +import SwiperComponent from "components/designSystems/taro/SwiperComponent"; +import { ValidationTypes } from "constants/WidgetValidation"; +import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory"; +import _ from "lodash"; + +class SwiperWidget extends BaseWidget { + static getPropertyPaneConfig() { + return [ + { + helpText: "轮播数据列表,通过 {{}} 进行数据绑定", + propertyName: "list", + label: "数据", + controlType: "INPUT_TEXT", + placeholderText: '例如 [{ "url": "val1", link: "val2" }]', + inputType: "ARRAY", + isBindProperty: true, + isTriggerProperty: false, + validation: { + type: ValidationTypes.OBJECT_ARRAY, + params: { + default: [], + }, + }, + evaluationSubstitutionType: EvaluationSubstitutionType.SMART_SUBSTITUTE, + }, + { + propertyName: "urlKey", + label: "图片字段", + controlType: "INPUT_TEXT", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + ]; + } + + getPageView() { + const { list, urlKey } = this.props; + return ( + + ); + } + + getWidgetType(): WidgetType { + return WidgetTypes.TARO_SWIPER_WIDGET; + } +} + +export interface SwiperWidgetProps extends WidgetProps { + list: any[]; + urlKey: string; +} + +export default SwiperWidget; +export const ProfiledSwiperWidget = SwiperWidget; diff --git a/app/client/src/widgets/taro/TabsWidget.tsx b/app/client/src/widgets/taro/TabsWidget.tsx new file mode 100644 index 0000000000..9d8f92eb3b --- /dev/null +++ b/app/client/src/widgets/taro/TabsWidget.tsx @@ -0,0 +1,136 @@ +import React from "react"; +import BaseWidget, { WidgetProps, WidgetState } from "../BaseWidget"; +import { WidgetType } from "constants/WidgetConstants"; +import ButtonComponent from "components/designSystems/taro/ButtonComponent"; +import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; +import { ValidationTypes } from "constants/WidgetValidation"; +import withMeta, { WithMeta } from "../MetaHOC"; + +class MTabsWidget extends BaseWidget { + state = { + isLoading: false, + }; + + static getPropertyPaneConfig() { + return [ + { + sectionName: "属性", + children: [ + { + propertyName: "text", + label: "按钮文字", + controlType: "INPUT_TEXT", + placeholderText: "输入按钮文字", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "color", + label: "按钮颜色", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "rounded", + label: "是否圆角", + controlType: "SWITCH", + isBindProperty: false, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "isVisible", + label: "是否可见", + helpText: "控制按钮显示/隐藏", + controlType: "SWITCH", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "isDisabled", + label: "禁用", + controlType: "SWITCH", + helpText: "禁止按钮交互", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + ], + }, + { + sectionName: "动作", + children: [ + { + helpText: "点击按钮时触发动作", + propertyName: "onClick", + label: "onClick", + controlType: "ACTION_SELECTOR", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: true, + }, + ], + }, + ]; + } + + onButtonClick = () => { + if (this.props.onClick) { + this.setState({ + isLoading: true, + }); + super.executeAction({ + triggerPropertyName: "onClick", + dynamicString: this.props.onClick, + event: { + type: EventType.ON_CLICK, + callback: this.handleActionComplete, + }, + }); + } + }; + + handleActionComplete = () => { + this.setState({ + isLoading: false, + }); + }; + + getPageView() { + return ( + + ); + } + + getWidgetType(): WidgetType { + return "TARO_BUTTON_WIDGET"; + } +} + +export interface MTabsWidgetProps extends WidgetProps, WithMeta { + text?: string; + color?: string; + onClick?: string; + rounded?: boolean; + isDisabled?: boolean; + isVisible?: boolean; +} + +interface TabsWidgetState extends WidgetState { + isLoading: boolean; +} + +export default MTabsWidget; +export const MProfiledTabsWidget = withMeta(MTabsWidget); diff --git a/app/client/src/widgets/taro/TextWidget.tsx b/app/client/src/widgets/taro/TextWidget.tsx new file mode 100644 index 0000000000..e84e762dcc --- /dev/null +++ b/app/client/src/widgets/taro/TextWidget.tsx @@ -0,0 +1,202 @@ +import React from "react"; +import BaseWidget, { WidgetProps, WidgetState } from "../BaseWidget"; +import { WidgetType, TextSize } from "constants/WidgetConstants"; +import TextComponent from "components/designSystems/taro/TextComponent"; +import { ValidationTypes } from "constants/WidgetValidation"; +import { DerivedPropertiesMap } from "utils/WidgetFactory"; + +class TextWidget extends BaseWidget { + static getPropertyPaneConfig() { + return [ + { + sectionName: "属性", + children: [ + { + propertyName: "text", + label: "文本", + controlType: "INPUT_TEXT", + placeholderText: "请输入文本内容", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "shouldScroll", + label: "允许滚动", + helpText: "内容超长时允许滚动,不然文本会被截断", + controlType: "SWITCH", + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "isVisible", + label: "是否可见", + controlType: "SWITCH", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + ], + }, + { + sectionName: "样式", + children: [ + { + propertyName: "backgroundColor", + label: "背景颜色", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "textColor", + label: "文本颜色", + controlType: "COLOR_PICKER", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { + type: ValidationTypes.TEXT, + params: { + regex: /^(?![<|{{]).+/, + }, + }, + }, + { + propertyName: "fontSize", + label: "字体大小", + controlType: "DROP_DOWN", + options: [ + { + label: "一级标题", + value: "HEADING1", + subText: "24px", + icon: "HEADING_ONE", + }, + { + label: "二级标题", + value: "HEADING2", + subText: "18px", + icon: "HEADING_TWO", + }, + { + label: "三级标题", + value: "HEADING3", + subText: "16px", + icon: "HEADING_THREE", + }, + { + label: "一级段落", + value: "PARAGRAPH", + subText: "14px", + icon: "PARAGRAPH", + }, + { + label: "二级段落", + value: "PARAGRAPH2", + subText: "12px", + icon: "PARAGRAPH_TWO", + }, + ], + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "fontStyle", + label: "字体风格", + controlType: "BUTTON_TABS", + options: [ + { + icon: "BOLD_FONT", + value: "BOLD", + }, + { + icon: "ITALICS_FONT", + value: "ITALIC", + }, + { + icon: "LINETHROUGH_FONT", + value: "LINETHROUGH", + }, + ], + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "textAlign", + label: "文字对齐", + controlType: "ICON_TABS", + options: [ + { + icon: "LEFT_ALIGN", + value: "LEFT", + }, + { + icon: "CENTER_ALIGN", + value: "CENTER", + }, + { + icon: "RIGHT_ALIGN", + value: "RIGHT", + }, + ], + defaultValue: "LEFT", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + ], + }, + ]; + } + + getPageView() { + return ( + + ); + } + + static getDerivedPropertiesMap(): DerivedPropertiesMap { + return { + value: `{{ this.text }}`, + }; + } + + getWidgetType(): WidgetType { + return "TARO_TEXT_WIDGET"; + } +} + +export type TextAlign = "LEFT" | "CENTER" | "RIGHT" | "JUSTIFY"; + +export interface TextStyles { + backgroundColor?: string; + textColor?: string; + fontStyle?: string; + fontSize?: TextSize; + textAlign?: TextAlign; +} + +export interface MTextWidgetProps extends WidgetProps, TextStyles { + text?: string; + isLoading: boolean; + shouldScroll: boolean; +} + +export default TextWidget; +export const MProfiledTextWidget = TextWidget; diff --git a/app/client/tsconfig.path.json b/app/client/tsconfig.path.json index 7f94edc294..91cc0a4bec 100644 --- a/app/client/tsconfig.path.json +++ b/app/client/tsconfig.path.json @@ -3,7 +3,9 @@ "baseUrl": "src", "paths": { "@appsmith/*": ["enterprise/*"], - "test/*": ["../test/*"] + "test/*": ["../test/*"], + "@tarojs/components$": ["../node_modules/@tarojs/components/dist-h5/react"], + "@tarojs/taro$": ["../node_modules/@tarojs/taro-h5/dist/index.cjs.js"] } } } diff --git a/app/client/yarn.lock b/app/client/yarn.lock index dea8f2e89e..3568cbb367 100644 --- a/app/client/yarn.lock +++ b/app/client/yarn.lock @@ -2998,6 +2998,11 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@stencil/core@2.9.0": + version "2.9.0" + resolved "https://registry.npmmirror.com/@stencil/core/download/@stencil/core-2.9.0.tgz#cbac84b996475b8fc983931539ed1261174e2df3" + integrity sha1-y6yEuZZHW4/Jg5MVOe0SYRdOLfM= + "@storybook/addon-actions@^5.3.19": version "5.3.21" resolved "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-5.3.21.tgz" @@ -3737,6 +3742,106 @@ "@svgr/plugin-svgo" "^4.3.1" loader-utils "^1.2.3" +"@taroify/core@^0.0.21-alpha.0": + version "0.0.21-alpha.0" + resolved "https://registry.npmmirror.com/@taroify/core/download/@taroify/core-0.0.21-alpha.0.tgz#f4892e124264d447ca22a2f186a259206e6eda39" + integrity sha512-32glY/TQTAQFBq5toMsDYPG2sJvrCVBdWl/6V2s3xPA1wrXYXNIYMipY+cJUWAbV5GRkmtYZUCvqxn5Q7gT4cQ== + dependencies: + "@taroify/hooks" "^0.0.21-alpha.0" + "@taroify/icons" "^0.0.21-alpha.0" + classnames "^2.2.6" + lodash "^4.17.21" + raf "^3.4.1" + react-is "^17.0.2" + react-transition-group "^4.4.1" + +"@taroify/hooks@^0.0.21-alpha.0": + version "0.0.21-alpha.0" + resolved "https://registry.npmmirror.com/@taroify/hooks/download/@taroify/hooks-0.0.21-alpha.0.tgz#eab174feb5c2b458480f3b80963ad1c893fab42c" + integrity sha512-X6Q7J0KxV7eLA85yX4aFsZc19GakYz4p22Q2R11hg5k5dD3SpepcaPxz4OGSedhX36eXFFum0a+mdYR9ONmiGQ== + dependencies: + lodash "^4.17.21" + react "^17.0.2" + +"@taroify/icons@^0.0.21-alpha.0": + version "0.0.21-alpha.0" + resolved "https://registry.npmmirror.com/@taroify/icons/download/@taroify/icons-0.0.21-alpha.0.tgz#12d0c7bab07021fccdb9f7e344571c840613d278" + integrity sha512-hM95Ee0bN9833EFpCRwJm64LbvFwD6uzLW5gR4Na8u+M7B0/IxqIkpyUpFJJOAbyQFsr8pIpJlCBEhFw0KvSug== + dependencies: + classnames "^2.2.6" + +"@tarojs/api@3.3.14": + version "3.3.14" + resolved "https://registry.npmmirror.com/@tarojs/api/download/@tarojs/api-3.3.14.tgz?cache=0&sync_timestamp=1636732246149&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40tarojs%2Fapi%2Fdownload%2F%40tarojs%2Fapi-3.3.14.tgz#b04cf5d8f3c153985d3e9dc199a03ef576017147" + integrity sha512-ZNnNP4wmZnTMV9XY4eCxlmUGGUfgNLVAr0e5CGxpbCVdY/SQWUo3Koc7893t1Jr+tijj6/rHzhLBfZ4HqcL6Ng== + dependencies: + "@babel/runtime" "^7.11.2" + "@tarojs/runtime" "3.3.14" + +"@tarojs/components@^3.3.14": + version "3.3.14" + resolved "https://registry.npmmirror.com/@tarojs/components/download/@tarojs/components-3.3.14.tgz#6c689ef7b752c879bdec15a13bf7fd88f5519a48" + integrity sha512-rJiLMSdLaF1oND0TH++CmsIE51mux+WRsT3kc8qN/Kn3f2NAd9H/g5gecb6CWeBHvj8qb21otdnjLgoTGtwKtA== + dependencies: + "@stencil/core" "2.9.0" + "@tarojs/taro" "3.3.14" + better-scroll "^1.14.1" + classnames "^2.2.5" + intersection-observer "^0.7.0" + omit.js "^1.0.0" + resolve-pathname "^3.0.0" + swiper "6.8.0" + weui "^1.1.2" + +"@tarojs/router@3.3.14": + version "3.3.14" + resolved "https://registry.npmmirror.com/@tarojs/router/download/@tarojs/router-3.3.14.tgz#6de6c182007f161689d5485980e72428ebf0fa60" + integrity sha512-8kRrYs490I50vTsv3424fW6aoiufhBYyswkN6BvqyIopShl22jJ9muE97uGUMvvuJRxf8SmlDo3IC8+Q9xykng== + dependencies: + "@tarojs/runtime" "3.3.14" + history "^5.1.0" + query-string "^6.13.8" + universal-router "^8.3.0" + url-parse "^1.4.7" + +"@tarojs/runtime@3.3.14": + version "3.3.14" + resolved "https://registry.npmmirror.com/@tarojs/runtime/download/@tarojs/runtime-3.3.14.tgz#d778f2da970433ca96a3316d83b6ad385efe4601" + integrity sha512-13Rup8kO0SnMBw+jk9k1GKfQE0nwmaC6biNtq8KKEIsVzGUrrf/UXDJACfbcypyChaSBlpaetODWitPX0lmNpQ== + dependencies: + "@tarojs/shared" "3.3.14" + inversify "5.1.1" + lodash-es "4.17.15" + reflect-metadata "^0.1.13" + +"@tarojs/shared@3.3.14": + version "3.3.14" + resolved "https://registry.npmmirror.com/@tarojs/shared/download/@tarojs/shared-3.3.14.tgz#dcb6a149cdafb97369a06d7bf74c8249894bb3ec" + integrity sha512-iowfmHKVV0cKLMtdNdYoYLQ/CCQ6cl9L2eJh/sJj1OvytxdxjCzyjyR1pJQYkyTPkwRtDweNwzRsezLQlRfBAA== + +"@tarojs/taro-h5@3.3.14": + version "3.3.14" + resolved "https://registry.npmmirror.com/@tarojs/taro-h5/download/@tarojs/taro-h5-3.3.14.tgz#7efbe33875e9d491df8acc11d9186c89c2a53e44" + integrity sha512-vB4w2iAyckvSyeHPMtI5eLDBOFLEFhtR8TuR4P/lh/HoYWglrt0jCjK7UQqtlvqtdSkUHxsGSyLHSNXPGWkjNg== + dependencies: + "@tarojs/api" "3.3.14" + "@tarojs/router" "3.3.14" + "@tarojs/runtime" "3.3.14" + base64-js "^1.3.0" + jsonp-retry "^1.0.3" + mobile-detect "^1.4.2" + raf "^3.4.1" + whatwg-fetch "^3.4.0" + +"@tarojs/taro@3.3.14": + version "3.3.14" + resolved "https://registry.npmmirror.com/@tarojs/taro/download/@tarojs/taro-3.3.14.tgz#5b804aa92bdad7023c16b59a7d0cb60534f7b120" + integrity sha512-6Qdl7fO0sltEFNnYI+rNaw/vzRDW1I+Vdo9dc39bc0NiL6BI30LtXcpMjsA9oZhVOtEBoMTZpiuAm3GPCaa82A== + dependencies: + "@tarojs/api" "3.3.14" + "@tarojs/runtime" "3.3.14" + "@tarojs/taro-h5" "3.3.14" + "@testing-library/dom@^7.28.1": version "7.30.1" resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-7.30.1.tgz" @@ -4020,10 +4125,6 @@ version "3.0.3" resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz" -"@types/minimist@^1.2.0": - version "1.2.1" - resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz" - "@types/moment-timezone@^0.5.10": version "0.5.30" resolved "https://registry.npmjs.org/@types/moment-timezone/-/moment-timezone-0.5.30.tgz" @@ -5282,6 +5383,11 @@ arr-union@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz" +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.nlark.com/array-find-index/download/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" @@ -5879,7 +5985,7 @@ babel-preset-react-app@^10.0.0: babel-plugin-macros "2.8.0" babel-plugin-transform-react-remove-prop-types "0.4.24" -babel-runtime@^6.11.6, babel-runtime@^6.26.0: +babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.23.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz" dependencies: @@ -5920,6 +6026,11 @@ base64-js@^1.0.2: version "1.3.1" resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz" +base64-js@^1.3.0: + version "1.5.1" + resolved "https://registry.nlark.com/base64-js/download/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha1-GxtEAWClv3rUC2UPCVljSBkDkwo= + base@^0.11.1: version "0.11.2" resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz" @@ -5946,6 +6057,13 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +better-scroll@^1.14.1: + version "1.15.2" + resolved "https://registry.nlark.com/better-scroll/download/better-scroll-1.15.2.tgz?cache=0&sync_timestamp=1627913074987&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fbetter-scroll%2Fdownload%2Fbetter-scroll-1.15.2.tgz#65ffc6058b8b4ff337b8dfad4bcb334d7699ceb6" + integrity sha1-Zf/GBYuLT/M3uN+tS8szTXaZzrY= + dependencies: + babel-runtime "^6.0.0" + bfj@^7.0.2: version "7.0.2" resolved "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz" @@ -5977,6 +6095,13 @@ blob-util@2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz" +block-stream@*: + version "0.0.9" + resolved "https://registry.nlark.com/block-stream/download/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + bluebird@^3.3.5, bluebird@^3.5.5, bluebird@^3.7.2: version "3.7.2" resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" @@ -6327,18 +6452,23 @@ camelcase-css@2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz" -camelcase-keys@^6.2.2: - version "6.2.2" - resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz" +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/camelcase-keys/download/camelcase-keys-2.1.0.tgz?cache=0&sync_timestamp=1633332959770&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fcamelcase-keys%2Fdownload%2Fcamelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= dependencies: - camelcase "^5.3.1" - map-obj "^4.0.0" - quick-lru "^4.0.1" + camelcase "^2.0.0" + map-obj "^1.0.0" camelcase@5.3.1, camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.npmmirror.com/camelcase/download/camelcase-2.1.1.tgz?cache=0&sync_timestamp=1636945151239&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fcamelcase%2Fdownload%2Fcamelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + camelcase@^6.0.0, camelcase@^6.1.0: version "6.2.0" resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz" @@ -7114,7 +7244,7 @@ cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.2: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" dependencies: @@ -7122,6 +7252,14 @@ cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +cross-spawn@^3.0.0: + version "3.0.1" + resolved "https://registry.nlark.com/cross-spawn/download/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" + integrity sha1-ElYDfsufDF9549bvE14wdwGEuYI= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + crypt@0.0.2: version "0.0.2" resolved "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz" @@ -7404,6 +7542,13 @@ cuid@^2.1.1: version "2.1.8" resolved "https://registry.npmjs.org/cuid/-/cuid-2.1.8.tgz" +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.npm.taobao.org/currently-unhandled/download/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + cyclist@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz" @@ -7547,14 +7692,7 @@ debug@^4.3.0, debug@~4.3.1: dependencies: ms "2.1.2" -decamelize-keys@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz" - dependencies: - decamelize "^1.1.0" - map-obj "^1.0.0" - -decamelize@^1.1.0, decamelize@^1.2.0: +decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" @@ -7861,6 +7999,13 @@ dom4@^2.1.5: version "2.1.5" resolved "https://registry.npmjs.org/dom4/-/dom4-2.1.5.tgz" +dom7@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/dom7/download/dom7-3.0.0.tgz#b861ce5d67a6becd7aaa3ad02942ff14b1240331" + integrity sha1-uGHOXWemvs16qjrQKUL/FLEkAzE= + dependencies: + ssr-window "^3.0.0-alpha.1" + domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz" @@ -8148,10 +8293,6 @@ entities@^2.0.0: version "2.0.3" resolved "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz" -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" - errno@^0.1.1: version "0.1.8" resolved "https://registry.nlark.com/errno/download/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" @@ -9013,6 +9154,11 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +filter-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.nlark.com/filter-obj/download/filter-obj-1.1.0.tgz?cache=0&sync_timestamp=1630004180503&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ffilter-obj%2Fdownload%2Ffilter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" + integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs= + finalhandler@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz" @@ -9058,6 +9204,14 @@ find-up@4.1.0, find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.npmmirror.com/find-up/download/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" @@ -9271,6 +9425,16 @@ fsevents@~2.3.1: version "2.3.2" resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" +fstream@^1.0.0, fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.npm.taobao.org/fstream/download/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha1-Touo7i1Ivk99DeUFRVVI6uWTIEU= + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + fsu@^1.0.2: version "1.1.1" resolved "https://registry.npmjs.org/fsu/-/fsu-1.1.1.tgz" @@ -9567,10 +9731,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 version "4.2.4" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz" -graceful-fs@^4.2.3: - version "4.2.6" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz" - graphql@^15.4.0: version "15.5.0" resolved "https://registry.npmjs.org/graphql/-/graphql-15.5.0.tgz" @@ -9609,10 +9769,6 @@ har-validator@~5.1.3: ajv "^6.12.3" har-schema "^2.0.0" -hard-rejection@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz" - harmony-reflect@^1.4.6: version "1.6.1" resolved "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.1.tgz" @@ -9787,6 +9943,13 @@ history@^4.10.1, history@^4.9.0: tiny-warning "^1.0.0" value-equal "^1.0.1" +history@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/history/download/history-5.1.0.tgz#2e93c09c064194d38d52ed62afd0afc9d9b01ece" + integrity sha1-LpPAnAZBlNONUu1ir9CvydmwHs4= + dependencies: + "@babel/runtime" "^7.7.6" + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" @@ -9820,12 +9983,6 @@ hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" -hosted-git-info@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz" - dependencies: - lru-cache "^6.0.0" - hpack.js@^2.1.6: version "2.1.6" resolved "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz" @@ -10126,6 +10283,18 @@ imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" +in-publish@^2.0.0: + version "2.0.1" + resolved "https://registry.nlark.com/in-publish/download/in-publish-2.0.1.tgz#948b1a535c8030561cea522f73f78f4be357e00c" + integrity sha1-lIsaU1yAMFYc6lIvc/ePS+NX4Aw= + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.nlark.com/indent-string/download/indent-string-2.1.0.tgz?cache=0&sync_timestamp=1622604582006&other_urls=https%3A%2F%2Fregistry.nlark.com%2Findent-string%2Fdownload%2Findent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + indent-string@^3.0.0: version "3.2.0" resolved "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz" @@ -10149,7 +10318,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" @@ -10245,6 +10414,11 @@ interpret@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz" +intersection-observer@^0.7.0: + version "0.7.0" + resolved "https://registry.npm.taobao.org/intersection-observer/download/intersection-observer-0.7.0.tgz#ee16bee978db53516ead2f0a8154b09b400bbdc9" + integrity sha1-7ha+6XjbU1FurS8KgVSwm0ALvck= + interweave-autolink@^4.4.2: version "4.4.2" resolved "https://registry.npmjs.org/interweave-autolink/-/interweave-autolink-4.4.2.tgz" @@ -10270,6 +10444,11 @@ invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: dependencies: loose-envify "^1.0.0" +inversify@5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/inversify/download/inversify-5.1.1.tgz?cache=0&sync_timestamp=1636450784676&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Finversify%2Fdownload%2Finversify-5.1.1.tgz#6fbd668c591337404e005a1946bfe0d802c08730" + integrity sha1-b71mjFkTN0BOAFoZRr/g2ALAhzA= + ip-regex@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz" @@ -10372,12 +10551,6 @@ is-core-module@^2.0.0: dependencies: has "^1.0.3" -is-core-module@^2.2.0: - version "2.4.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz" - dependencies: - has "^1.0.3" - is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz" @@ -10454,6 +10627,11 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" +is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/is-finite/download/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha1-kEE1x3+0LAZB1qobzbxNqo2ggvM= + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" @@ -10565,7 +10743,7 @@ is-path-inside@^3.0.1: version "3.0.2" resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz" -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: +is-plain-obj@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz" @@ -10651,6 +10829,11 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.npm.taobao.org/is-utf8/download/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + is-what@^3.12.0: version "3.14.1" resolved "https://registry.npm.taobao.org/is-what/download/is-what-3.14.1.tgz#e1222f46ddda85dead0fd1c9df131760e77755c1" @@ -11506,6 +11689,13 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +jsonp-retry@^1.0.3: + version "1.0.3" + resolved "https://registry.npm.taobao.org/jsonp-retry/download/jsonp-retry-1.0.3.tgz#9e6b18b02ec767a621dd44b4e99439a8a43a6419" + integrity sha1-nmsYsC7HZ6Yh3US06ZQ5qKQ6ZBk= + dependencies: + object-assign "^4.1.1" + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz" @@ -11564,7 +11754,7 @@ kind-of@^5.0.0: version "5.1.0" resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" -kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: +kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.3" resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" @@ -11755,6 +11945,17 @@ listr@^0.14.3: p-map "^2.0.0" rxjs "^6.3.3" +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.nlark.com/load-json-file/download/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + load-json-file@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz" @@ -11835,6 +12036,11 @@ lodash-es@4.17.14: version "4.17.14" resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.14.tgz" +lodash-es@4.17.15: + version "4.17.15" + resolved "https://registry.npm.taobao.org/lodash-es/download/lodash-es-4.17.15.tgz?cache=0&sync_timestamp=1613835893273&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash-es%2Fdownload%2Flodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" + integrity sha1-Ib2Wg5NUQS8j16EDQOXqxu5FXXg= + lodash-es@^4.17.15, lodash-es@^4.17.21: version "4.17.21" resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz" @@ -11979,6 +12185,14 @@ lottie-web@^5.7.4: version "5.7.4" resolved "https://registry.npmjs.org/lottie-web/-/lottie-web-5.7.4.tgz" +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.nlark.com/loud-rejection/download/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + lower-case@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.1.tgz" @@ -11999,7 +12213,7 @@ lowlight@~1.11.0: fault "^1.0.2" highlight.js "~9.13.0" -lru-cache@^4.1.5: +lru-cache@^4.0.1, lru-cache@^4.1.5: version "4.1.5" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz" dependencies: @@ -12063,14 +12277,10 @@ map-cache@^0.2.2: version "0.2.2" resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" -map-obj@^1.0.0: +map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz" -map-obj@^4.0.0: - version "4.2.1" - resolved "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz" - map-or-similar@^1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz" @@ -12210,22 +12420,21 @@ memory-fs@^0.5.0: errno "^0.1.3" readable-stream "^2.0.1" -meow@^9.0.0: - version "9.0.0" - resolved "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz" +meow@^3.7.0: + version "3.7.0" + resolved "https://registry.nlark.com/meow/download/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= dependencies: - "@types/minimist" "^1.2.0" - camelcase-keys "^6.2.2" - decamelize "^1.2.0" - decamelize-keys "^1.1.0" - hard-rejection "^2.1.0" - minimist-options "4.1.0" - normalize-package-data "^3.0.0" - read-pkg-up "^7.0.1" - redent "^3.0.0" - trim-newlines "^3.0.0" - type-fest "^0.18.0" - yargs-parser "^20.2.3" + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" merge-class-names@^1.1.1: version "1.3.0" @@ -12386,15 +12595,7 @@ minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch dependencies: brace-expansion "^1.1.7" -minimist-options@4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz" - dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - kind-of "^6.0.3" - -minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" @@ -12462,7 +12663,7 @@ mkdirp@0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz" -mkdirp@0.5.5, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.1: +mkdirp@0.5.5, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" dependencies: @@ -12472,6 +12673,11 @@ mkdirp@1.x, mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" +mobile-detect@^1.4.2: + version "1.4.5" + resolved "https://registry.npm.taobao.org/mobile-detect/download/mobile-detect-1.4.5.tgz?cache=0&sync_timestamp=1615628315030&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmobile-detect%2Fdownload%2Fmobile-detect-1.4.5.tgz#da393c3c413ca1a9bcdd9ced653c38281c0fb6ad" + integrity sha1-2jk8PEE8oam83ZztZTw4KBwPtq0= + mocha-junit-reporter@^1.23.3: version "1.23.3" resolved "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-1.23.3.tgz" @@ -12752,20 +12958,23 @@ node-forge@^0.10.0: version "0.10.0" resolved "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz" -node-gyp@^7.1.0: - version "7.1.2" - resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz" +node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.npmmirror.com/node-gyp/download/node-gyp-3.8.0.tgz?cache=0&sync_timestamp=1636105025371&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fnode-gyp%2Fdownload%2Fnode-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + integrity sha1-VAMEJhwzDoDQ1e3OJTpoyzlkIYw= dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.3" - nopt "^5.0.0" - npmlog "^4.1.2" - request "^2.88.2" - rimraf "^3.0.2" - semver "^7.3.2" - tar "^6.0.2" - which "^2.0.2" + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" node-int64@^0.4.0: version "0.4.0" @@ -12822,20 +13031,23 @@ node-releases@^1.1.29, node-releases@^1.1.61: version "1.1.61" resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.61.tgz" -node-sass@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/node-sass/-/node-sass-6.0.1.tgz" +node-sass@4.14.1: + version "4.14.1" + resolved "https://registry.npmmirror.com/node-sass/download/node-sass-4.14.1.tgz#99c87ec2efb7047ed638fb4c9db7f3a42e2217b5" + integrity sha1-mch+wu+3BH7WOPtMnbfzpC4iF7U= dependencies: async-foreach "^0.1.3" chalk "^1.1.1" - cross-spawn "^7.0.3" + cross-spawn "^3.0.0" gaze "^1.0.0" get-stdin "^4.0.1" glob "^7.0.3" + in-publish "^2.0.0" lodash "^4.17.15" - meow "^9.0.0" + meow "^3.7.0" + mkdirp "^0.5.1" nan "^2.13.2" - node-gyp "^7.1.0" + node-gyp "^3.8.0" npmlog "^4.0.0" request "^2.88.0" sass-graph "2.2.5" @@ -12848,13 +13060,14 @@ nopt@1.0.10: dependencies: abbrev "1" -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz" +"nopt@2 || 3": + version "3.0.6" + resolved "https://registry.npm.taobao.org/nopt/download/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= dependencies: abbrev "1" -normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" dependencies: @@ -12863,15 +13076,6 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-package-data@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz" - dependencies: - hosted-git-info "^4.0.1" - resolve "^1.20.0" - semver "^7.3.4" - validate-npm-package-license "^3.0.1" - normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz" @@ -12925,7 +13129,7 @@ npm-run-path@^4.0.0: dependencies: path-key "^3.0.0" -npmlog@^4.0.0, npmlog@^4.1.2: +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz" dependencies: @@ -13054,6 +13258,13 @@ obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" +omit.js@^1.0.0: + version "1.0.2" + resolved "https://registry.npm.taobao.org/omit.js/download/omit.js-1.0.2.tgz#91a14f0eba84066dfa015bf30e474c47f30bc858" + integrity sha1-kaFPDrqEBm36AVvzDkdMR/MLyFg= + dependencies: + babel-runtime "^6.23.0" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" @@ -13159,10 +13370,23 @@ os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz" -os-tmpdir@~1.0.2: +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.npm.taobao.org/os-homedir/download/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" +osenv@0: + version "0.1.5" + resolved "https://registry.nlark.com/osenv/download/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha1-hc36+uso6Gd/QW4odZK18/SepBA= + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + ospath@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz" @@ -13393,6 +13617,13 @@ path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz" +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.nlark.com/path-exists/download/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" @@ -13431,10 +13662,24 @@ path-to-regexp@^1.7.0: dependencies: isarray "0.0.1" +path-to-regexp@^3.1.0: + version "3.2.0" + resolved "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-3.2.0.tgz#fa7877ecbc495c601907562222453c43cc204a5f" + integrity sha1-+nh37LxJXGAZB1YiIkU8Q8wgSl8= + path-to-regexp@^6.2.0: version "6.2.0" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.0.tgz" +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.nlark.com/path-type/download/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + path-type@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz" @@ -14568,6 +14813,16 @@ query-string@^4.1.0: object-assign "^4.1.0" strict-uri-encode "^1.0.0" +query-string@^6.13.8: + version "6.14.1" + resolved "https://registry.nlark.com/query-string/download/query-string-6.14.1.tgz?cache=0&sync_timestamp=1624297034221&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fquery-string%2Fdownload%2Fquery-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" + integrity sha1-esLcpG2n8wlEm6D4ax/SglWwyGo= + dependencies: + decode-uri-component "^0.2.0" + filter-obj "^1.1.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz" @@ -14580,10 +14835,6 @@ querystringify@^2.1.1: version "2.2.0" resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz" -quick-lru@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz" - raf-schd@^4.0.2: version "4.0.2" resolved "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.2.tgz" @@ -15383,6 +15634,11 @@ react-is@^17.0.1: version "17.0.1" resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz" +react-is@^17.0.2: + version "17.0.2" + resolved "https://registry.npmmirror.com/react-is/download/react-is-17.0.2.tgz?cache=0&sync_timestamp=1637079520171&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Freact-is%2Fdownload%2Freact-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha1-5pHUqOnHiTZWVVOas3J2Kw77VPA= + react-json-view@^1.19.1: version "1.19.1" resolved "https://registry.npmjs.org/react-json-view/-/react-json-view-1.19.1.tgz" @@ -15710,6 +15966,16 @@ react-transition-group@^4, react-transition-group@^4.3.0: loose-envify "^1.4.0" prop-types "^15.6.2" +react-transition-group@^4.4.1: + version "4.4.2" + resolved "https://registry.nlark.com/react-transition-group/download/react-transition-group-4.4.2.tgz?cache=0&sync_timestamp=1622301030407&other_urls=https%3A%2F%2Fregistry.nlark.com%2Freact-transition-group%2Fdownload%2Freact-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470" + integrity sha1-i1mlbwnO17VcvVPDZ2i5IokNVHA= + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react-use-gesture@^7.0.4: version "7.0.16" resolved "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-7.0.16.tgz" @@ -15753,12 +16019,28 @@ react@^16.12.0, react@^16.8.3, react@^16.8.5: object-assign "^4.1.1" prop-types "^15.6.2" +react@^17.0.2: + version "17.0.2" + resolved "https://registry.npmmirror.com/react/download/react-17.0.2.tgz?cache=0&sync_timestamp=1637079519783&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Freact%2Fdownload%2Freact-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha1-0LXMUW0p6z7uOD91tihkz7aAADc= + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + reactcss@^1.2.0: version "1.2.3" resolved "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz" dependencies: lodash "^4.0.1" +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/read-pkg-up/download/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz" @@ -15781,6 +16063,15 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.nlark.com/read-pkg/download/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + read-pkg@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz" @@ -15900,6 +16191,14 @@ recursive-readdir@2.2.2: dependencies: minimatch "3.0.4" +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.nlark.com/redent/download/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + redent@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz" @@ -15960,6 +16259,11 @@ redux-saga@^1.1.3: loose-envify "^1.4.0" symbol-observable "^1.2.0" +reflect-metadata@^0.1.13: + version "0.1.13" + resolved "https://registry.npm.taobao.org/reflect-metadata/download/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha1-Z648pXyXKiqhZCsQ/jY/4y1J3Ag= + refractor@^2.4.1: version "2.10.1" resolved "https://registry.npmjs.org/refractor/-/refractor-2.10.1.tgz" @@ -16123,6 +16427,13 @@ repeat-string@^1.5.4, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.nlark.com/repeating/download/repeating-2.0.1.tgz?cache=0&sync_timestamp=1622605325095&other_urls=https%3A%2F%2Fregistry.nlark.com%2Frepeating%2Fdownload%2Frepeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + replace-ext@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz" @@ -16147,7 +16458,7 @@ request-promise-native@^1.0.8: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.88.0, request@^2.88.2: +request@^2.87.0, request@^2.88.0, request@^2.88.2: version "2.88.2" resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz" dependencies: @@ -16261,13 +16572,6 @@ resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.13 dependencies: path-parse "^1.0.6" -resolve@^1.20.0: - version "1.20.0" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz" - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - restore-cursor@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz" @@ -16320,15 +16624,15 @@ rgba-regex@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz" -rimraf@2.6.3, rimraf@~2.6.2: - version "2.6.3" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz" +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3, rimraf@^2.7.1: + version "2.7.1" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" dependencies: glob "^7.1.3" -rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3, rimraf@^2.7.1: - version "2.7.1" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" +rimraf@2.6.3, rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz" dependencies: glob "^7.1.3" @@ -16565,7 +16869,7 @@ semver@7.3.2: version "7.3.2" resolved "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz" -semver@7.x, semver@^7.3.4: +semver@7.x: version "7.3.5" resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz" dependencies: @@ -16581,6 +16885,11 @@ semver@^7.2.1, semver@^7.3.2: dependencies: lru-cache "^6.0.0" +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.nlark.com/semver/download/semver-5.3.0.tgz?cache=0&sync_timestamp=1622604551741&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsemver%2Fdownload%2Fsemver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= + send@0.17.1: version "0.17.1" resolved "https://registry.npmjs.org/send/-/send-0.17.1.tgz" @@ -17008,6 +17317,11 @@ spdy@^4.0.2: select-hose "^2.0.0" spdy-transport "^3.0.0" +split-on-first@^1.0.0: + version "1.1.0" + resolved "https://registry.nlark.com/split-on-first/download/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + integrity sha1-9hCv7uOxK84dDDBCXnY5i3gkml8= + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz" @@ -17032,6 +17346,11 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +ssr-window@^3.0.0, ssr-window@^3.0.0-alpha.1: + version "3.0.0" + resolved "https://registry.npmmirror.com/ssr-window/download/ssr-window-3.0.0.tgz#fd5b82801638943e0cc704c4691801435af7ac37" + integrity sha1-/VuCgBY4lD4MxwTEaRgBQ1r3rDc= + ssri@^6.0.1: version "6.0.2" resolved "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz" @@ -17155,6 +17474,11 @@ strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz" +strict-uri-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.npm.taobao.org/strict-uri-encode/download/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= + string-argv@^0.3.0: version "0.3.1" resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" @@ -17301,6 +17625,13 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.nlark.com/strip-bom/download/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" @@ -17324,6 +17655,13 @@ strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.nlark.com/strip-indent/download/strip-indent-1.0.1.tgz?cache=0&sync_timestamp=1620053310624&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fstrip-indent%2Fdownload%2Fstrip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + strip-indent@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz" @@ -17460,6 +17798,14 @@ svgo@^1.0.0, svgo@^1.2.2: unquote "~1.1.1" util.promisify "~1.0.0" +swiper@6.8.0: + version "6.8.0" + resolved "https://registry.npmmirror.com/swiper/download/swiper-6.8.0.tgz#61c850f49ba778e403f00a01fe0b768bd85d0d20" + integrity sha1-YchQ9JuneOQD8AoB/gt2i9hdDSA= + dependencies: + dom7 "^3.0.0" + ssr-window "^3.0.0" + symbol-observable@^1.0.4, symbol-observable@^1.1.0, symbol-observable@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz" @@ -17492,6 +17838,15 @@ tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz" +tar@^2.0.0: + version "2.2.2" + resolved "https://registry.nlark.com/tar/download/tar-2.2.2.tgz?cache=0&sync_timestamp=1629994598621&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ftar%2Fdownload%2Ftar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" + integrity sha1-DKiEhWLHKZuLRG/2pNYM27I+3EA= + dependencies: + block-stream "*" + fstream "^1.0.12" + inherits "2" + tar@^6.0.2: version "6.0.5" resolved "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz" @@ -17808,9 +18163,10 @@ tr46@^2.0.2: dependencies: punycode "^2.1.1" -trim-newlines@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz" +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.nlark.com/trim-newlines/download/trim-newlines-1.0.0.tgz?cache=0&sync_timestamp=1623341510447&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ftrim-newlines%2Fdownload%2Ftrim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= trim-trailing-lines@^1.0.0: version "1.1.3" @@ -17941,10 +18297,6 @@ type-fest@^0.11.0: version "0.11.0" resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz" -type-fest@^0.18.0: - version "0.18.1" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz" - type-fest@^0.3.1: version "0.3.1" resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz" @@ -18157,6 +18509,13 @@ unist-util-visit@^1.0.0, unist-util-visit@^1.4.0: dependencies: unist-util-visit-parents "^2.0.0" +universal-router@^8.3.0: + version "8.3.0" + resolved "https://registry.nlark.com/universal-router/download/universal-router-8.3.0.tgz?cache=0&sync_timestamp=1624462107331&other_urls=https%3A%2F%2Fregistry.nlark.com%2Funiversal-router%2Fdownload%2Funiversal-router-8.3.0.tgz#533bce135d7b1abf591421c5d2028d54407a34a0" + integrity sha1-UzvOE117Gr9ZFCHF0gKNVEB6NKA= + dependencies: + path-to-regexp "^3.1.0" + universalify@^0.1.0: version "0.1.2" resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" @@ -18228,6 +18587,14 @@ url-parse@^1.4.3: querystringify "^2.1.1" requires-port "^1.0.0" +url-parse@^1.4.7: + version "1.5.3" + resolved "https://registry.nlark.com/url-parse/download/url-parse-1.5.3.tgz#71c1303d38fb6639ade183c2992c8cc0686df862" + integrity sha1-ccEwPTj7Zjmt4YPCmSyMwGht+GI= + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + url-search-params-polyfill@^8.0.0: version "8.1.0" resolved "https://registry.npmjs.org/url-search-params-polyfill/-/url-search-params-polyfill-8.1.0.tgz" @@ -18624,6 +18991,11 @@ websocket-extensions@>=0.1.1: version "0.1.4" resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz" +weui@^1.1.2: + version "1.1.3" + resolved "https://registry.npmmirror.com/weui/download/weui-1.1.3.tgz?cache=0&sync_timestamp=1634013113866&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fweui%2Fdownload%2Fweui-1.1.3.tgz#0f0899bb61bb2ec603b2648367a8139298f81514" + integrity sha1-DwiZu2G7LsYDsmSDZ6gTkpj4FRQ= + whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz" @@ -18634,7 +19006,7 @@ whatwg-fetch@>=0.10.0, whatwg-fetch@^3.4.1: version "3.4.1" resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz" -whatwg-fetch@^3.0.0: +whatwg-fetch@^3.0.0, whatwg-fetch@^3.4.0: version "3.6.2" resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz" @@ -18654,7 +19026,7 @@ which-module@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz" -which@1.3.1, which@^1.2.9, which@^1.3.1: +which@1, which@1.3.1, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" dependencies: @@ -18999,10 +19371,6 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^20.2.3: - version "20.2.9" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" - yargs-unparser@1.6.0: version "1.6.0" resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz" diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CloudOSConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CloudOSConfig.java index da168b6836..b30d6b5e32 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CloudOSConfig.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CloudOSConfig.java @@ -13,6 +13,9 @@ public class CloudOSConfig { @Value("${pageplug.cloudos.mock_baseurl}") String mockUrl; + @Value("${pageplug.cloudos.db_baseurl}") + String dbUrl; + @Value("${pageplug.cloudos.in_cloudos}") Boolean inCloudOS; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Application.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Application.java index 9e9e634bed..ded6707707 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Application.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Application.java @@ -56,10 +56,8 @@ public class Application extends BaseDomain { String icon; - @JsonIgnore AppLayout unpublishedAppLayout; - @JsonIgnore AppLayout publishedAppLayout; Boolean forkingEnabled; @@ -118,6 +116,7 @@ public class Application extends BaseDomain { TABLET, MOBILE, FLUID, + MOBILE_FLUID, } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationPageServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationPageServiceImpl.java index ea712d996a..3e6ca0153c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationPageServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationPageServiceImpl.java @@ -15,10 +15,7 @@ import com.appsmith.server.domains.NewPage; import com.appsmith.server.domains.Organization; import com.appsmith.server.domains.Page; import com.appsmith.server.domains.User; -import com.appsmith.server.dtos.ActionDTO; -import com.appsmith.server.dtos.ApplicationPagesDTO; -import com.appsmith.server.dtos.PageDTO; -import com.appsmith.server.dtos.PageNameIdDTO; +import com.appsmith.server.dtos.*; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.repositories.ApplicationRepository; @@ -255,6 +252,15 @@ public class ApplicationPageServiceImpl implements ApplicationPageService { return applicationWithPoliciesMono .flatMap(applicationService::createDefault) + .flatMap(savedApplication -> { + final Application.AppLayout appLayout = savedApplication.getPublishedAppLayout(); + if (appLayout != null && appLayout.getType() == Application.AppLayout.Type.MOBILE_FLUID) { + final ApplicationAccessDTO applicationAccessDTO = new ApplicationAccessDTO(); + applicationAccessDTO.setPublicAccess(true); + return this.applicationService.changeViewAccess(savedApplication.getId(), applicationAccessDTO); + } + return Mono.just(savedApplication); + }) .flatMap(savedApplication -> { PageDTO page = new PageDTO(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/CloudOSActionSolution.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/CloudOSActionSolution.java index dfecb5a9c7..f51a17b418 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/CloudOSActionSolution.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/CloudOSActionSolution.java @@ -113,8 +113,13 @@ public class CloudOSActionSolution { String componentId = instance.get("component_id"); String serviceAddress = instance.get("service_address"); String datasourceName = componentName == null ? componentId : componentName; + String dbPrefix = cloudOSConfig.getDbUrl(); return datasourceService.findByNameAndOrganizationId(datasourceName, application.getOrganizationId(), AclPermission.MANAGE_DATASOURCES) .flatMap(datasource -> { + final String oldUrl = datasource.getDatasourceConfiguration().getUrl(); + if (oldUrl.contains(dbPrefix)) { + return Mono.just(datasource); + } final Datasource deployedDatasource = new Datasource(); final DatasourceConfiguration datasourceConfiguration = new DatasourceConfiguration(); datasourceConfiguration.setUrl(serviceAddress); @@ -221,6 +226,14 @@ public class CloudOSActionSolution { final String componentId = (String) bp.get("componentId"); final String componentDisplay = componentName == null ? componentId : componentName; List> cloudOSApiList = (List>) bp.get("apis"); + log.debug("绑定组件 " + componentName + " 的API"); + log.debug(cloudOSApiList.toString()); + Boolean isDbApi = cloudOSApiList.stream().anyMatch(ca -> { + final String apiKey = (String) ca.get("apiKey"); + return apiKey != null; + }); + final String apiHost = isDbApi ? cloudOSConfig.getDbUrl() : cloudOSConfig.getMockUrl() + "/" + projectId + "/" + componentId; + log.debug("数据源地址:" + apiHost); // create new datasource Datasource newSource = new Datasource(); @@ -229,7 +242,7 @@ public class CloudOSActionSolution { newSource.setName(componentDisplay); DatasourceConfiguration datasourceConfiguration = new DatasourceConfiguration(); - datasourceConfiguration.setUrl(cloudOSConfig.getMockUrl() + "/" + projectId + "/" + componentId); + datasourceConfiguration.setUrl(apiHost); ArrayList properties = new ArrayList<>(); properties.add(new Property("isSendSessionEnabled", "N")); properties.add(new Property("sessionSignatureKey", "")); diff --git a/app/server/appsmith-server/src/main/resources/application.properties b/app/server/appsmith-server/src/main/resources/application.properties index c8f9098820..14f575dccf 100644 --- a/app/server/appsmith-server/src/main/resources/application.properties +++ b/app/server/appsmith-server/src/main/resources/application.properties @@ -101,5 +101,6 @@ google.recaptcha.key.secret= ${APPSMITH_RECAPTCHA_SECRET_KEY:} # CloudOS config pageplug.cloudos.api_baseurl = ${CLOUDOS_API_BASE_URL:} pageplug.cloudos.mock_baseurl = ${CLOUDOS_MOCK_BASE_URL:} +pageplug.cloudos.db_baseurl = ${CLOUDOS_DB_BASE_URL:} pageplug.cloudos.in_cloudos = ${CLOUDOS_IN_CLOUDOS:false} pageplug.cloudos.jwt_secret_key = ${CLOUDOS_JWT_SECRET_KET:} \ No newline at end of file diff --git a/app/server/envs/dev.env.example b/app/server/envs/dev.env.example index 29da7d1db1..370220aa76 100644 --- a/app/server/envs/dev.env.example +++ b/app/server/envs/dev.env.example @@ -13,6 +13,7 @@ APPSMITH_CODEC_SIZE=10 CLOUDOS_API_BASE_URL="http://10.10.11.20:8035" CLOUDOS_MOCK_BASE_URL="http://10.10.11.20:8899" +CLOUDOS_DB_BASE_URL="http://db-manager.dev.staros.local/api/db-manager" CLOUDOS_IN_CLOUDOS=false CLOUDOS_JWT_SECRET_KET="jKriFBzevooCpDi"