Skip to content

Commit

Permalink
add Cube Loading to Query Result Panel (#3173)
Browse files Browse the repository at this point in the history
  • Loading branch information
MauricioUyaguari authored May 21, 2024
1 parent 8b1d04a commit 052f22e
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/hot-cheetahs-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@finos/legend-query-builder': patch
---

Change the query builder results panel loading indicator.
5 changes: 5 additions & 0 deletions .changeset/plenty-bananas-boil.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@finos/legend-art': patch
---

Add CubesLoadingIndicator and CubesLoadingIndicatorIcon components.
1 change: 1 addition & 0 deletions packages/legend-art/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export * from './icon/LegendLogo.js';
export * from './icon/SVGIcon.js';

export * from './loader/LoadingIcon.js';
export * from './loader/CubesLoadingIndicator.js';

export * from './input/Input.js';

Expand Down
58 changes: 58 additions & 0 deletions packages/legend-art/src/loader/CubesLoadingIndicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright (c) 2020-present, Goldman Sachs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import clsx from 'clsx';

export interface CubesLoadingIndicatorProps
extends React.HtmlHTMLAttributes<HTMLDivElement> {
isLoading: boolean;
}

export interface CubesLoadingIndicatorIconProps {
size?: 'sm' | 'md' | 'lg';
}

export const CubesLoadingIndicatorIcon: React.FC<
CubesLoadingIndicatorIconProps
> = (props) => {
const { size = 'md' } = props;
return (
<div className={clsx('cubes-icon', `cubes-icon--${size}`)}>
<i className="cubes-icon__icon" aria-hidden="true"></i>
<i className="cubes-icon__icon" aria-hidden="true"></i>
<i className="cubes-icon__icon" aria-hidden="true"></i>
<i className="cubes-icon__icon" aria-hidden="true"></i>
</div>
);
};

export const CubesLoadingIndicator: React.FC<CubesLoadingIndicatorProps> = (
props,
) => {
const { isLoading, children, className, ...rest } = props;

return (
<div
className={clsx('cubes-loading-indicator', {
'cubes-loading-indicator--loading': isLoading,
className,
})}
{...rest}
>
{children}
</div>
);
};
138 changes: 138 additions & 0 deletions packages/legend-art/style/components/_cubes-loading-indicator.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/**
* Copyright (c) 2020-present, Goldman Sachs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

@use 'sass:math';

$loading-icon-frame-rate: math.div(100, 8);
$loading-icon-full-duration: 1.6s;
$loading-icon-frame-duration: math.div($loading-icon-full-duration, 8);

$loading-icon-square-state-off: rotateX(90deg);
$loading-icon-square-state-on: rotateX(0deg);

$flip-step-1: $loading-icon-frame-rate * 0;
$flip-step-2: $loading-icon-frame-rate * 1;
$flip-step-3: $loading-icon-frame-rate * 4;
$flip-step-4: $loading-icon-frame-rate * 5;

$loading-icon-size-md: 32px;
$loading-icon-size-sm: 16px;
$loading-icon-size-lg: 64px;

.cubes-loading-indicator {
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
z-index: 1;
display: none;
justify-content: center;
align-items: center;

&--loading {
display: flex;
}
}

.cubes-icon {
position: relative;

&--md {
height: $loading-icon-size-md;
width: $loading-icon-size-md;
}

&--sm {
width: $loading-icon-size-sm;
height: $loading-icon-size-sm;
}

&--lg {
width: $loading-icon-size-lg;
height: $loading-icon-size-lg;

&__icon {
width: calc(50% - 2px);
height: calc(50% - 2px);
}
}

&__icon {
width: calc(50% - 1px);
height: calc(50% - 1px);
position: absolute;
background: var(--color-legacylight-light-blue-100);
animation: flip-animation $loading-icon-full-duration infinite;
transform: $loading-icon-square-state-off;

// Top-left
&:nth-child(1) {
top: 0;
left: 0;
animation-delay: $loading-icon-frame-duration * 0;
}
// Top-Right
&:nth-child(2) {
top: 0;
left: 50%;
animation-delay: $loading-icon-frame-duration * 1;
}
// Bottom-Right
&:nth-child(3) {
top: 50%;
left: 50%;
animation-delay: $loading-icon-frame-duration * 2;
}
// Bottom-Left
&:nth-child(4) {
top: 50%;
left: 0;
animation-delay: $loading-icon-frame-duration * 3;
}
}
}

// The animation loop is split into 8 frames
// The On/Off state is controlled through the variables

// Frame 0: 90deg rotation along X axis (not visible)
// Frame 1: 0deg rotation along X axis (fully visible)
// Frame 2:
// Frame 3:
// Frame 4: Continue from 0dev
// Frame 5: rotate to 90deg again (hidden)
// Frame 6:
// Frame 7:

@keyframes flip-animation {
#{$flip-step-1}% {
transform: $loading-icon-square-state-off;
opacity: 0.5;
}
#{$flip-step-2}% {
transform: $loading-icon-square-state-on;
opacity: 1;
}
#{$flip-step-3}% {
transform: $loading-icon-square-state-on;
opacity: 1;
}
#{$flip-step-4}% {
transform: $loading-icon-square-state-off;
opacity: 0.5;
}
}
1 change: 1 addition & 0 deletions packages/legend-art/style/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
@forward 'components/selector-input';
@forward 'components/tree-view';
@forward 'components/markdown-viewer';
@forward 'components/cubes-loading-indicator';

// Reset (override library styles)
@forward 'reset/mui';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import {
BlankPanelContent,
PanelLoadingIndicator,
PlayIcon,
DropdownMenu,
MenuContent,
Expand All @@ -43,6 +42,8 @@ import {
CsvIcon,
DebugIcon,
ReportIcon,
CubesLoadingIndicatorIcon,
CubesLoadingIndicator,
} from '@finos/legend-art';
import { observer } from 'mobx-react-lite';
import { flowResult } from 'mobx';
Expand Down Expand Up @@ -334,6 +335,9 @@ export const QueryBuilderResultPanel = observer(
</MenuContentItem>
));

const isLoading =
resultState.isRunningQuery || resultState.isGeneratingPlan;

return (
<div
data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_RESULT_PANEL}
Expand Down Expand Up @@ -613,18 +617,16 @@ export const QueryBuilderResultPanel = observer(
))}
</div>
</div>
<PanelContent>
<PanelLoadingIndicator
isLoading={
resultState.isRunningQuery || resultState.isGeneratingPlan
}
/>
{!executionResult && (
<PanelContent className="query-builder__result__content">
<CubesLoadingIndicator isLoading={isLoading}>
<CubesLoadingIndicatorIcon />
</CubesLoadingIndicator>
{!executionResult && !isLoading && (
<BlankPanelContent>
Build or load a valid query first
</BlankPanelContent>
)}
{executionResult && (
{executionResult && !isLoading && (
<div className="query-builder__result__values">
<QueryBuilderResultValues
executionResult={executionResult}
Expand Down
4 changes: 4 additions & 0 deletions packages/legend-query-builder/style/_query-builder.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1322,6 +1322,10 @@
width: 100%;
}

&__content {
position: relative;
}

&__analytics {
font-size: 1.2rem;
color: var(--color-dark-grey-400);
Expand Down

0 comments on commit 052f22e

Please sign in to comment.