From 359ceb62a2964d4f2a5b38947b8eef5ef2dcc8d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bonnet?= Date: Mon, 6 Jan 2025 17:28:37 +0100 Subject: [PATCH] feat(service-list): feedback (#1802) * Allow tooltip for small size * Hide force run when deploying service * Remove animation for deployment queue --- .../environment-action-toolbar.tsx | 45 +++++- .../service-action-toolbar.tsx | 133 ++++++++++++------ .../__snapshots__/service-list.spec.tsx.snap | 32 ++--- .../src/lib/service-list/service-list.tsx | 37 ++--- .../service-template-indicator.tsx | 2 +- libs/shared/ui/src/index.ts | 1 + .../animated-gradient-text.spec.tsx | 19 +++ .../animated-gradient-text.stories.tsx | 22 +++ .../animated-gradient-text.tsx | 28 ++++ tailwind-workspace-preset.js | 8 ++ 10 files changed, 239 insertions(+), 88 deletions(-) create mode 100644 libs/shared/ui/src/lib/components/animated-gradient-text/animated-gradient-text.spec.tsx create mode 100644 libs/shared/ui/src/lib/components/animated-gradient-text/animated-gradient-text.stories.tsx create mode 100644 libs/shared/ui/src/lib/components/animated-gradient-text/animated-gradient-text.tsx diff --git a/libs/domains/environments/feature/src/lib/environment-action-toolbar/environment-action-toolbar.tsx b/libs/domains/environments/feature/src/lib/environment-action-toolbar/environment-action-toolbar.tsx index af07069e610..683bed8e5c3 100644 --- a/libs/domains/environments/feature/src/lib/environment-action-toolbar/environment-action-toolbar.tsx +++ b/libs/domains/environments/feature/src/lib/environment-action-toolbar/environment-action-toolbar.tsx @@ -1,5 +1,6 @@ import { type Environment, OrganizationEventTargetType, StateEnum } from 'qovery-typescript-axios' import { useLocation } from 'react-router-dom' +import { match } from 'ts-pattern' import { AUDIT_LOGS_PARAMS_URL, ENVIRONMENT_LOGS_URL, ENVIRONMENT_STAGES_URL } from '@qovery/shared/routes' import { ActionToolbar, @@ -112,7 +113,23 @@ function MenuManageDeployment({ >
- + {match(state) + .with( + 'DEPLOYING', + 'RESTARTING', + 'BUILDING', + 'DELETING', + 'CANCELING', + 'STOPPING', + 'DEPLOYMENT_QUEUED', + 'DELETE_QUEUED', + 'STOP_QUEUED', + 'RESTART_QUEUED', + () => + ) + .otherwise(() => ( + + ))}
@@ -139,10 +156,28 @@ function MenuManageDeployment({ Stop )} - - } onSelect={openUpdateAllModal}> - Deploy latest version for.. - + {match(state) + .with( + 'DEPLOYING', + 'RESTARTING', + 'BUILDING', + 'DELETING', + 'CANCELING', + 'STOPPING', + 'DEPLOYMENT_QUEUED', + 'DELETE_QUEUED', + 'STOP_QUEUED', + 'RESTART_QUEUED', + () => null + ) + .otherwise(() => ( + <> + + } onSelect={openUpdateAllModal}> + Deploy latest version for.. + + + ))} ) diff --git a/libs/domains/services/feature/src/lib/service-action-toolbar/service-action-toolbar.tsx b/libs/domains/services/feature/src/lib/service-action-toolbar/service-action-toolbar.tsx index 3269f90f56d..4d7d00c0ee4 100644 --- a/libs/domains/services/feature/src/lib/service-action-toolbar/service-action-toolbar.tsx +++ b/libs/domains/services/feature/src/lib/service-action-toolbar/service-action-toolbar.tsx @@ -386,24 +386,39 @@ function MenuManageDeployment({ Restart Service )} - {service.serviceType === 'JOB' && ( - } - onSelect={() => - openModal({ - content: ( - - ), - }) - } - > - Force Run - - )} + {service.serviceType === 'JOB' && + match(state) + .with( + 'DEPLOYING', + 'RESTARTING', + 'BUILDING', + 'DELETING', + 'CANCELING', + 'STOPPING', + 'DEPLOYMENT_QUEUED', + 'DELETE_QUEUED', + 'STOP_QUEUED', + 'RESTART_QUEUED', + () => null + ) + .otherwise(() => ( + } + onSelect={() => + openModal({ + content: ( + + ), + }) + } + > + Force Run + + ))} {isStopAvailable(state) && ( } onSelect={mutationStop}> Stop @@ -418,19 +433,35 @@ function MenuManageDeployment({ .with({ serviceType: 'APPLICATION' }, ({ git_repository }) => git_repository) .with({ serviceType: 'JOB' }, ({ source }) => source.docker?.git_repository) .exhaustive() - return ( - <> - - {gitRepository && ( - } - onSelect={() => deployCommitVersion(service, gitRepository, 'Deploy another version')} - > - Deploy another version - - )} - - ) + + return match(state) + .with( + 'DEPLOYING', + 'RESTARTING', + 'BUILDING', + 'DELETING', + 'CANCELING', + 'STOPPING', + 'DEPLOYMENT_QUEUED', + 'DELETE_QUEUED', + 'STOP_QUEUED', + 'RESTART_QUEUED', + () => null + ) + .otherwise( + () => + gitRepository && ( + <> + + } + onSelect={() => deployCommitVersion(service, gitRepository, 'Deploy another version')} + > + Deploy another version + + + ) + ) } ) .with( @@ -442,19 +473,35 @@ function MenuManageDeployment({ .with({ serviceType: 'CONTAINER' }, (source) => source) .with({ serviceType: 'JOB' }, ({ source: { image } }) => image) .exhaustive() - return ( - containerSource.tag && ( - <> - - } - onSelect={() => deployTagVersion(service, containerSource)} - > - Deploy another version - - + + return match(state) + .with( + 'DEPLOYING', + 'RESTARTING', + 'BUILDING', + 'DELETING', + 'CANCELING', + 'STOPPING', + 'DEPLOYMENT_QUEUED', + 'DELETE_QUEUED', + 'STOP_QUEUED', + 'RESTART_QUEUED', + () => null + ) + .otherwise( + () => + containerSource.tag && ( + <> + + } + onSelect={() => deployTagVersion(service, containerSource)} + > + Deploy another version + + + ) ) - ) } ) .with( diff --git a/libs/domains/services/feature/src/lib/service-list/__snapshots__/service-list.spec.tsx.snap b/libs/domains/services/feature/src/lib/service-list/__snapshots__/service-list.spec.tsx.snap index ab7f6b109cc..9fccb25692f 100644 --- a/libs/domains/services/feature/src/lib/service-list/__snapshots__/service-list.spec.tsx.snap +++ b/libs/domains/services/feature/src/lib/service-list/__snapshots__/service-list.spec.tsx.snap @@ -6,7 +6,7 @@ exports[`ServiceList should match snapshot 1`] = ` class="flex grow flex-col justify-between" > @@ -29,7 +29,7 @@ exports[`ServiceList should match snapshot 1`] = `
Target version
( - - {upperCaseFirstLetter(s).replace('_', ' ')} - - . - . - . - - + {upperCaseFirstLetter(s).replace('_', ' ')}... )) + .with('CANCELED', () => Last deployment aborted) .with('DEPLOYING', 'RESTARTING', 'BUILDING', 'DELETING', 'CANCELING', 'STOPPING', (s) => ( e.stopPropagation()} > - - {upperCaseFirstLetter(s)} - - . - . - . + + + {upperCaseFirstLetter(s)}... - {' '} - + )) - .with('DEPLOYMENT_ERROR', 'DELETE_ERROR', 'STOP_ERROR', 'RESTART_ERROR', () => ( + .with('DEPLOYMENT_ERROR', 'DELETE_ERROR', 'STOP_ERROR', 'RESTART_ERROR', 'BUILD_ERROR', () => ( { const service = info.row.original @@ -532,8 +523,8 @@ export function ServiceList({ environment, className, ...props }: ServiceListPro {datasource.type.toLowerCase().replace('sql', 'SQL').replace('db', 'DB')} - - v.{datasource.version} + v + {datasource.version} ) @@ -633,7 +624,7 @@ export function ServiceList({ environment, className, ...props }: ServiceListPro header: 'Last deployment', enableColumnFilter: false, enableSorting: true, - size: 5, + size: 3, cell: (info) => { const service = info.row.original const value = info.getValue() @@ -779,7 +770,7 @@ export function ServiceList({ environment, className, ...props }: ServiceListPro return (
- + {table.getHeaderGroups().map((headerGroup) => ( diff --git a/libs/domains/services/feature/src/lib/service-template-indicator/service-template-indicator.tsx b/libs/domains/services/feature/src/lib/service-template-indicator/service-template-indicator.tsx index 0614ff768da..93fcb96cdd1 100644 --- a/libs/domains/services/feature/src/lib/service-template-indicator/service-template-indicator.tsx +++ b/libs/domains/services/feature/src/lib/service-template-indicator/service-template-indicator.tsx @@ -42,7 +42,7 @@ export function ServiceTemplateIndicator({ + diff --git a/libs/shared/ui/src/index.ts b/libs/shared/ui/src/index.ts index 2a6368d3dc9..ab6aa54022a 100644 --- a/libs/shared/ui/src/index.ts +++ b/libs/shared/ui/src/index.ts @@ -101,6 +101,7 @@ export * from './lib/components/error-boundary/error-boundary' export * from './lib/components/indicator/indicator' export * from './lib/components/segmented-control/segmented-control' export * from './lib/components/board/board' +export * from './lib/components/animated-gradient-text/animated-gradient-text' export * from './lib/utils/toast' export * from './lib/utils/toast-error' export * from './lib/utils/ansi' diff --git a/libs/shared/ui/src/lib/components/animated-gradient-text/animated-gradient-text.spec.tsx b/libs/shared/ui/src/lib/components/animated-gradient-text/animated-gradient-text.spec.tsx new file mode 100644 index 00000000000..14be717405c --- /dev/null +++ b/libs/shared/ui/src/lib/components/animated-gradient-text/animated-gradient-text.spec.tsx @@ -0,0 +1,19 @@ +import { renderWithProviders, screen } from '@qovery/shared/util-tests' +import { AnimatedGradientText } from './animated-gradient-text' + +describe('AnimatedGradientText', () => { + it('renders children correctly', () => { + const testText = 'Hello World' + renderWithProviders({testText}) + expect(screen.getByText(testText)).toBeInTheDocument() + }) + + it('sets correct shimmer width style variable', () => { + const shimmerWidth = 200 + const { container } = renderWithProviders( + Test + ) + const element = container.firstChild as HTMLElement + expect(element.style.getPropertyValue('--shiny-width')).toBe('200px') + }) +}) diff --git a/libs/shared/ui/src/lib/components/animated-gradient-text/animated-gradient-text.stories.tsx b/libs/shared/ui/src/lib/components/animated-gradient-text/animated-gradient-text.stories.tsx new file mode 100644 index 00000000000..18378336314 --- /dev/null +++ b/libs/shared/ui/src/lib/components/animated-gradient-text/animated-gradient-text.stories.tsx @@ -0,0 +1,22 @@ +import type { Meta } from '@storybook/react' +import Icon from '../icon/icon' +import { AnimatedGradientText } from './animated-gradient-text' + +const Story: Meta = { + component: AnimatedGradientText, + title: 'Text Animations/Animated Gradient Text', +} + +export const Primary = { + render: () => ( + + ✨ Animated Gradient Text + + + ), +} + +export default Story diff --git a/libs/shared/ui/src/lib/components/animated-gradient-text/animated-gradient-text.tsx b/libs/shared/ui/src/lib/components/animated-gradient-text/animated-gradient-text.tsx new file mode 100644 index 00000000000..b181115f9a8 --- /dev/null +++ b/libs/shared/ui/src/lib/components/animated-gradient-text/animated-gradient-text.tsx @@ -0,0 +1,28 @@ +import { type CSSProperties, type PropsWithChildren } from 'react' +import { twMerge } from '@qovery/shared/util-js' + +export interface AnimatedGradientTextProps extends PropsWithChildren { + className?: string + shimmerWidth?: number +} + +// Inspired by https://magicui.design/docs/components/animated-shiny-text +export function AnimatedGradientText({ children, className, shimmerWidth = 100 }: AnimatedGradientTextProps) { + return ( + + {children} + + ) +} + +export default AnimatedGradientText diff --git a/tailwind-workspace-preset.js b/tailwind-workspace-preset.js index fc9b3761f0e..1eb721ce768 100644 --- a/tailwind-workspace-preset.js +++ b/tailwind-workspace-preset.js @@ -356,6 +356,14 @@ module.exports = { '200px 0 rgba(255, 255, 255, 0), 200px 0 rgba(255, 255, 255, 0), 200px 0 rgba(255, 255, 255, 0), 200px 0 rgba(255, 255, 255, 0)', }, }, + 'shiny-text': { + '0%': { + 'background-position': 'calc(-100% - var(--shiny-width)) 0', + }, + '100%': { + 'background-position': 'calc(100% + var(--shiny-width)) 0', + }, + }, ...slideEntrances(), ...slideExits(), },