diff --git a/client/packages/lowcoder-design/src/components/Loading.tsx b/client/packages/lowcoder-design/src/components/Loading.tsx index 21718bd07..414096e33 100644 --- a/client/packages/lowcoder-design/src/components/Loading.tsx +++ b/client/packages/lowcoder-design/src/components/Loading.tsx @@ -1,5 +1,6 @@ import styled, { css } from "styled-components"; import { CSSProperties } from "react"; +import { default as Skeleton } from "antd/es/skeleton"; type LoadingContainerProps = { $backgroundColor: string; @@ -12,6 +13,8 @@ const LoadingWrapper = styled.div` flex-direction: column; align-items: center; justify-content: center; + width: 100%; + height: 100%; `; // Loading @@ -61,6 +64,10 @@ const Load2 = styled.div` linear-gradient(to right, ${(props) => props.$color}a3, ${(props) => props.$color}1a); `; +const StyledSkeleton = styled(Skeleton)` + height: 100%; +`; + type LoadingProps = { backgroundColor?: string; color?: string; @@ -77,14 +84,15 @@ export const Loading = (props: LoadingProps) => { }; return ( - + {/* - + */} + ); }; diff --git a/client/packages/lowcoder-design/src/components/button.tsx b/client/packages/lowcoder-design/src/components/button.tsx index 3cb3be148..be045d7d7 100644 --- a/client/packages/lowcoder-design/src/components/button.tsx +++ b/client/packages/lowcoder-design/src/components/button.tsx @@ -1,4 +1,6 @@ import Button, { ButtonProps } from "antd/es/button"; +import Spin from "antd/es/spin"; +import LoadingOutlined from "@ant-design/icons/LoadingOutlined" import styled, { css } from "styled-components"; import { Loading } from "./Loading"; import * as React from "react"; @@ -206,10 +208,10 @@ const TacoButton = forwardRef( {props.icon} {props.children} - } style={loadingStyle} - backgroundColor={loadingBackground} - color={loadingColor} /> ) : ( diff --git a/client/packages/lowcoder/index.html b/client/packages/lowcoder/index.html index 08c68d08f..2c3d6cd34 100644 --- a/client/packages/lowcoder/index.html +++ b/client/packages/lowcoder/index.html @@ -57,32 +57,8 @@
- - - - - - - - - - - - +
diff --git a/client/packages/lowcoder/src/api/commonSettingApi.ts b/client/packages/lowcoder/src/api/commonSettingApi.ts index 1e7d23227..6b80e4527 100644 --- a/client/packages/lowcoder/src/api/commonSettingApi.ts +++ b/client/packages/lowcoder/src/api/commonSettingApi.ts @@ -66,6 +66,8 @@ export interface ThemeDetail { boxShadowColor?: string; animationIterationCount?: string; components?: Record; + showComponentLoadingIndicators?: boolean; + showDataLoadingIndicators?: boolean; } export function getThemeDetailName(key: keyof ThemeDetail) { diff --git a/client/packages/lowcoder/src/components/ThemeSettingsSelector.tsx b/client/packages/lowcoder/src/components/ThemeSettingsSelector.tsx index 1aef3f138..91aa91d1d 100644 --- a/client/packages/lowcoder/src/components/ThemeSettingsSelector.tsx +++ b/client/packages/lowcoder/src/components/ThemeSettingsSelector.tsx @@ -4,7 +4,7 @@ import { ConfigItem, Radius, Margin, Padding, GridColumns, BorderWidth, BorderSt import { isValidColor, toHex } from "components/colorSelect/colorUtils"; import { ColorSelect } from "components/colorSelect"; import { TacoInput } from "components/tacoInput"; -import { Slider } from "antd"; +import { Slider, Switch } from "antd"; import { ExpandIcon, CompressIcon, @@ -27,6 +27,8 @@ export type configChangeParams = { borderWidth?: string; fontFamily?: string; components?: Record, + showComponentLoadingIndicators?: boolean; + showDataLoadingIndicators?: boolean; }; type ColorConfigProps = { @@ -46,6 +48,8 @@ type ColorConfigProps = { margin?: string; padding?: string; gridColumns?: string; // Added By Aqib Mirza + showComponentLoadingIndicators?: boolean; + showDataLoadingIndicators?: boolean; }; export default function ThemeSettingsSelector(props: ColorConfigProps) { @@ -63,7 +67,9 @@ export default function ThemeSettingsSelector(props: ColorConfigProps) { borderStyle: defaultBorderStyle, borderWidth: defaultBorderWidth, borderColor: defaultBorderColor, - fontFamily: defaultFontFamily + fontFamily: defaultFontFamily, + showComponentLoadingIndicators: defaultShowComponentLoaders, + showDataLoadingIndicators: defaultShowDataLoaders, } = props; const configChangeWithDebounce = _.debounce(configChange, 0); @@ -76,6 +82,8 @@ export default function ThemeSettingsSelector(props: ColorConfigProps) { const [borderWidth, setBorderWidth] = useState(defaultBorderWidth); const [borderColor, setBorderColor] = useState(defaultBorderColor); const [fontFamily, setFontFamily] = useState(defaultFontFamily); + const [showComponentLoaders, setComponentLoaders] = useState(defaultShowComponentLoaders); + const [showDataLoaders, setDataLoaders] = useState(defaultShowDataLoaders); const varName = `(${themeSettingKey})`; @@ -229,14 +237,26 @@ export default function ThemeSettingsSelector(props: ColorConfigProps) { setFontFamily(defaultFontFamily); }, [defaultFontFamily]); + useEffect(() => { + setComponentLoaders(defaultShowComponentLoaders); + }, [defaultShowComponentLoaders]); + + useEffect(() => { + setDataLoaders(defaultShowDataLoaders); + }, [defaultShowDataLoaders]); + return ( -
-
- {name} {showVarName && {varName}} + {themeSettingKey !== "showDataLoadingIndicators" + && themeSettingKey !== "showComponentLoadingIndicators" + && ( +
+
+ {name} {showVarName && {varName}} +
+
{desc}
-
{desc}
-
+ )} {themeSettingKey !== "radius" && themeSettingKey !== "margin" && @@ -244,7 +264,9 @@ export default function ThemeSettingsSelector(props: ColorConfigProps) { themeSettingKey !== "gridColumns" && themeSettingKey !== "borderStyle" && themeSettingKey !== "borderWidth" && - themeSettingKey !== "fontFamily" && ( + themeSettingKey !== "fontFamily" && + themeSettingKey !== "showComponentLoadingIndicators" && + themeSettingKey !== "showDataLoadingIndicators" && (
)} - - {themeSettingKey === "fontFamily" && (
)} + {themeSettingKey === "showComponentLoadingIndicators" && ( +
+ { + debugger; + setComponentLoaders(value) + configChange({ themeSettingKey, showComponentLoadingIndicators: value}); + }} + /> + {name} +
+ )} + + {themeSettingKey === "showDataLoadingIndicators" && ( +
+ { + setDataLoaders(value) + configChange({ themeSettingKey, showDataLoadingIndicators: value}); + }} + /> + {name} +
+ )} ); } diff --git a/client/packages/lowcoder/src/comps/comps/appSettingsComp.tsx b/client/packages/lowcoder/src/comps/comps/appSettingsComp.tsx index 667c2b9ae..a471dea7c 100644 --- a/client/packages/lowcoder/src/comps/comps/appSettingsComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/appSettingsComp.tsx @@ -111,10 +111,6 @@ const DivStyled = styled.div` > div:first-child { margin-bottom: 6px; } - - .tooltipLabel { - white-space: nowrap; - } } // custom styles for icon selector diff --git a/client/packages/lowcoder/src/comps/comps/lazyLoadComp/lazyLoadComp.tsx b/client/packages/lowcoder/src/comps/comps/lazyLoadComp/lazyLoadComp.tsx index fbb8ccc06..981d3852f 100644 --- a/client/packages/lowcoder/src/comps/comps/lazyLoadComp/lazyLoadComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/lazyLoadComp/lazyLoadComp.tsx @@ -5,11 +5,12 @@ import { GreyTextColor } from "constants/style"; import log from "loglevel"; import { Comp, CompAction, CompConstructor, CompParams, customAction, isCustomAction } from "lowcoder-core"; import { WhiteLoading } from "lowcoder-design"; -import { useState } from "react"; +import { useContext, useState } from "react"; import { useMount } from "react-use"; import styled from "styled-components"; -import { RemoteCompInfo, RemoteCompLoader } from "types/remoteComp"; +import { RemoteCompInfo } from "types/remoteComp"; import { withErrorBoundary } from "comps/generators/withErrorBoundary"; +import { ThemeContext } from "@lowcoder-ee/comps/utils/themeContext"; const ViewError = styled.div` display: flex; @@ -52,6 +53,8 @@ interface LazyCompViewProps { function LazyCompView(props: React.PropsWithChildren) { const { loadComp, loadingElement, errorElement } = props; const [error, setError] = useState(""); + const currentTheme = useContext(ThemeContext)?.theme; + const showComponentLoadingIndicators = currentTheme?.showComponentLoadingIndicators; useMount(() => { setError(""); @@ -71,14 +74,14 @@ function LazyCompView(props: React.PropsWithChildren) { ); } + if (!showComponentLoadingIndicators) return<>; + if (loadingElement) { return {loadingElement()}; } return ( - - - + ); } diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx index 9861d5a23..7c3176a71 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx @@ -40,11 +40,14 @@ import { SlotConfigContext } from "comps/controls/slotControl"; import { EmptyContent } from "pages/common/styledComponent"; import { messageInstance } from "lowcoder-design/src/components/GlobalInstances"; import { ReactRef, ResizeHandleAxis } from "layout/gridLayoutPropTypes"; -import { CellColorViewType, ColumnComp } from "./column/tableColumnComp"; +import { CellColorViewType } from "./column/tableColumnComp"; import { defaultTheme } from "@lowcoder-ee/constants/themeConstants"; import { childrenToProps } from "@lowcoder-ee/comps/generators/multi"; import { getVerticalMargin } from "@lowcoder-ee/util/cssUtil"; import { TableSummary } from "./tableSummaryComp"; +import Skeleton from "antd/es/skeleton"; +import { SkeletonButtonProps } from "antd/es/skeleton/Button"; +import { ThemeContext } from "@lowcoder-ee/comps/utils/themeContext"; export const EMPTY_ROW_KEY = 'empty_row'; @@ -438,6 +441,27 @@ const TableTd = styled.td<{ } `; +const TableTdLoading = styled(Skeleton.Button)` + width: 90% !important; + display: table !important; + + .ant-skeleton-button { + min-width: auto !important; + display: block !important; + ${(props) => props.$tableSize === 'small' && ` + height: 20px !important; + `} + ${(props) => props.$tableSize === 'middle' && ` + height: 24px !important; + `} + ${(props) => props.$tableSize === 'large' && ` + height: 28px !important; + `} + } +`; + const ResizeableTitle = (props: any) => { const { onResize, onResizeStop, width, viewModeResizable, ...restProps } = props; const [widthChild, setWidthChild] = useState(0); @@ -503,6 +527,7 @@ type CustomTableProps = Omit, "components" | columnsStyle: TableColumnStyleType; size?: string; rowAutoHeight?: boolean; + customLoading?: boolean; onCellClick: (columnName: string, dataIndex: string) => void; }; @@ -519,6 +544,7 @@ function TableCellView(props: { linkStyle: TableColumnLinkStyleType; tableSize?: string; autoHeight?: boolean; + loading?: boolean; }) { const { record, @@ -533,6 +559,7 @@ function TableCellView(props: { linkStyle, tableSize, autoHeight, + loading, ...restProps } = props; @@ -590,7 +617,10 @@ function TableCellView(props: { $tableSize={tableSize} $autoHeight={autoHeight} > - {children} + {loading + ? + : children + } ); } @@ -628,6 +658,8 @@ function ResizeableTable(props: CustomTableProps { const { width, style, linkStyle, cellColorFn, ...restCol } = col; const resizeWidth = (resizeData.index === index ? resizeData.width : col.width) ?? 0; @@ -661,7 +693,8 @@ function ResizeableTable(props: CustomTableProps { props.onCellClick(col.titleText, String(col.dataIndex)); - } + }, + loading: customLoading, }), onHeaderCell: () => ({ width: resizeWidth, @@ -732,6 +765,8 @@ export function TableCompView(props: { }) { const [emptyRowsMap, setEmptyRowsMap] = useState>({}); const editorState = useContext(EditorContext); + const currentTheme = useContext(ThemeContext)?.theme; + const showDataLoadingIndicators = currentTheme?.showDataLoadingIndicators; const { width, ref } = useResizeDetector({ refreshMode: "debounce", refreshRate: 600, @@ -956,6 +991,12 @@ export function TableCompView(props: { } const hideScrollbar = !showHorizontalScrollbar && !showVerticalScrollbar; + const showTableLoading = loading || + // fixme isLoading type + ((showDataLoadingIndicators || compChildren.showDataLoadSpinner.getView()) && + (compChildren.data as any).isLoading()) || + compChildren.loading.getView(); + return ( { comp.children.selectedCell.dispatchChangeValueAction({ name: columnName, diff --git a/client/packages/lowcoder/src/constants/themeConstants.ts b/client/packages/lowcoder/src/constants/themeConstants.ts index 455046fce..827602d7d 100644 --- a/client/packages/lowcoder/src/constants/themeConstants.ts +++ b/client/packages/lowcoder/src/constants/themeConstants.ts @@ -23,6 +23,8 @@ const theme = { boxShadow: "", boxShadowColor: "", animationIterationCount: "", + showComponentLoadingIndicators: true, + showDataLoadingIndicators: true, }; const text = { diff --git a/client/packages/lowcoder/src/i18n/locales/de.ts b/client/packages/lowcoder/src/i18n/locales/de.ts index cdaa0c80d..4d2bd1b94 100644 --- a/client/packages/lowcoder/src/i18n/locales/de.ts +++ b/client/packages/lowcoder/src/i18n/locales/de.ts @@ -1507,7 +1507,7 @@ export const de: typeof en = { "dynamicColumnConfig": "Säuleneinstellung", "dynamicColumnConfigDesc": "Dynamische Spalteneinstellungen. Akzeptiert ein Array von Spaltennamen. In der Standardeinstellung sind alle Spalten sichtbar. Beispiel: [%r@\\\"id%r@\\\", %r@\\\"name%r@\\\"]", "position": "Position", - "showDataLoadSpinner": "Spinner beim Laden von Daten anzeigen", + "showDataLoadSpinner": "Ladeanzeige anzeigen", "showValue": "Wert anzeigen", "expandable": "Ausbaufähig", "configExpandedView": "Expandierte Ansicht konfigurieren", diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 61d0ae8a6..71c260e19 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -1991,7 +1991,7 @@ export const en = { "dynamicColumnConfig": "Visible Columns", "dynamicColumnConfigDesc": "Dynamic Column Visibility. Accepts an Array of Column Names. All Columns Are Visible by Default. Example: [\"id\", \"name\"]", "position": "Position", - "showDataLoadSpinner": "Show Spinner During Data Loading", + "showDataLoadSpinner": "Show Loading Indicator", "showValue": "Show Value", "expandable": "Expandable", "configExpandedView": "Configure Expanded View", @@ -2606,7 +2606,10 @@ export const en = { "containerHeaderPadding": "Header Padding", "containerheaderpaddingDesc": "Default header padding typically used for most components", "gridColumns": "Canvas Grid Columns", - "gridColumnsDesc": "Default number of columns typically used for most containers" + "gridColumnsDesc": "Default number of columns typically used for most containers", + "loadingIndicators": "Loading Indicators", + "showComponentLoadingIndicators": "Show loading indicators when component load", + "showDataLoadingIndicators": "Show loading indicators when data load" }, "pluginSetting": { "title": "Plugins", diff --git a/client/packages/lowcoder/src/i18n/locales/pt.ts b/client/packages/lowcoder/src/i18n/locales/pt.ts index 1a84ea9f4..22689ce5a 100644 --- a/client/packages/lowcoder/src/i18n/locales/pt.ts +++ b/client/packages/lowcoder/src/i18n/locales/pt.ts @@ -2039,7 +2039,7 @@ export const pt: typeof en = { "dynamicColumnConfig": "Configuração de Coluna", "dynamicColumnConfigDesc": "Configurações de coluna dinâmica. Aceita um array de nomes de colunas. Todas as colunas são visíveis por padrão. Exemplo: [\"id\", \"name\"]", "position": "Posição", - "showDataLoadSpinner": "Mostrar Spinner Durante o Carregamento de Dados", + "showDataLoadSpinner": "Mostrar indicador de carregamento", "showValue": "Mostrar Valor", "expandable": "Expansível", "configExpandedView": "Configurar Visualização Expandida", diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts index 679eb9d12..d1203fa8e 100644 --- a/client/packages/lowcoder/src/i18n/locales/zh.ts +++ b/client/packages/lowcoder/src/i18n/locales/zh.ts @@ -1536,7 +1536,7 @@ export const zh: typeof en = { dynamicColumnConfig: "列设置", dynamicColumnConfigDesc: "动态列设置.接受一个列名的数组,默认情况下所有列都可见.\n" + `示例:["id", "name"]`, position: "位置", - showDataLoadSpinner: "数据加载时显示加载指示器", + showDataLoadSpinner: "显示加载指示器", showValue: "显示值", expandable: "可展开", configExpandedView: "配置展开视图", diff --git a/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx b/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx index a38afd104..98ff83f92 100644 --- a/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx +++ b/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx @@ -16,6 +16,7 @@ import { default as Skeleton } from "antd/es/skeleton"; import { default as Spin } from "antd/es/spin"; import { useTemplateViewMode, useUserViewMode } from "util/hooks"; import { ProductLoading } from "components/ProductLoading"; +import { default as LoadingOutlined } from "@ant-design/icons/LoadingOutlined"; const StyledSkeleton = styled(Skeleton)` padding: 16px; @@ -40,7 +41,7 @@ export const EditorLoadingSpin = (props: { height?: string | number }) => { const { height = "100vh" } = props; return (
- + }/>
); }; diff --git a/client/packages/lowcoder/src/pages/setting/theme/detail/index.tsx b/client/packages/lowcoder/src/pages/setting/theme/detail/index.tsx index 513a598cf..8013a1b7c 100644 --- a/client/packages/lowcoder/src/pages/setting/theme/detail/index.tsx +++ b/client/packages/lowcoder/src/pages/setting/theme/detail/index.tsx @@ -174,7 +174,7 @@ class ThemeDetailPage extends React.Component { this.configChange(params); }} @@ -483,7 +502,7 @@ class ThemeDetailPage extends React.Component { this.configChange(params); }} @@ -493,7 +512,7 @@ class ThemeDetailPage extends React.Component { this.configChange(params); }} @@ -503,7 +522,7 @@ class ThemeDetailPage extends React.Component { this.configChange(params); }} @@ -513,7 +532,7 @@ class ThemeDetailPage extends React.Component { this.configChange(params); }} @@ -523,7 +542,28 @@ class ThemeDetailPage extends React.Component { + this.configChange(params); + }} + /> + } + {layoutSettingsItem.type == "showComponentLoadingIndicators" && + { + console.log('configChange', params); + this.configChange(params); + }} + /> + } + {layoutSettingsItem.type == "showDataLoadingIndicators" && + { this.configChange(params); }} diff --git a/client/packages/lowcoder/src/pages/setting/theme/themeConstant.tsx b/client/packages/lowcoder/src/pages/setting/theme/themeConstant.tsx index a68d453d1..e0fbab429 100644 --- a/client/packages/lowcoder/src/pages/setting/theme/themeConstant.tsx +++ b/client/packages/lowcoder/src/pages/setting/theme/themeConstant.tsx @@ -32,6 +32,8 @@ export const themeTemplateList = [ gridColumns: "24", //Added By Aqib Mirza margin: "3px", padding: "3px", + showComponentLoadingIndicators: true, + showDataLoadingIndicators: true, }, }, { @@ -49,6 +51,8 @@ export const themeTemplateList = [ gridColumns: "24", //Added By Aqib Mirza margin: "3px", padding: "3px", + showComponentLoadingIndicators: true, + showDataLoadingIndicators: true, }, }, { @@ -66,6 +70,8 @@ export const themeTemplateList = [ gridColumns: "24", //Added By Aqib Mirza margin: "3px", padding: "3px", + showComponentLoadingIndicators: true, + showDataLoadingIndicators: true, }, }, ];