chore: git tag - adding ui improvments (#39972)

## Description
- Changes the look of TabRelease to be cleaner
- Removes beta tag when `release_git_package_enabled` feature flag is
enabled

## Automation

/ok-to-test tags="@tag.Git,@tag.Module"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/14173821996>
> Commit: eeac00c923171e1b728b5079332d504a2dbc51d1
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=14173821996&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Git,@tag.Module`
> Spec:
> <hr>Mon, 31 Mar 2025 15:16:47 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a configuration flag for managing the release package
feature.

- **Style**
  - Updated module labels to conditionally display a beta indicator.
- Revised interface text for releasing versions and displaying commit
details.
- Enhanced layout and visual styling for commit information and release
version selection.

- **Refactor**
- Streamlined the release button logic to require only a release
version, improving usability.
- Removed unused props and logic from the release version radio group
component.
- Restructured the latest commit information component for improved
visual hierarchy.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Rudraprasad Das 2025-03-31 19:23:11 +02:00 committed by GitHub
parent aaec892526
commit c675c0307b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 117 additions and 94 deletions

View File

@ -2372,10 +2372,12 @@ export const EDITOR_PANE_TEXTS = {
query_create_tab_title: () => "Create new query from", query_create_tab_title: () => "Create new query from",
widgets_create_tab_title: () => "Drag & drop UI elements", widgets_create_tab_title: () => "Drag & drop UI elements",
js_create_tab_title: () => "Create JS object from", js_create_tab_title: () => "Create JS object from",
js_create_modules: () => "JS modules (Beta)", js_create_modules: (isBeta: boolean) =>
`JS modules ${isBeta ? "(Beta)" : ""}`,
queries_create_from_existing: () => "Datasources", queries_create_from_existing: () => "Datasources",
queries_create_new: () => "Quick actions", queries_create_new: () => "Quick actions",
queries_create_modules: () => "Query modules (Beta)", queries_create_modules: (isBeta: boolean) =>
`Query modules ${isBeta ? "(Beta)" : ""}`,
loading_building_blocks: () => "Loading building blocks", loading_building_blocks: () => "Loading building blocks",
empty_search_result: (type: string) => `No ${type} match your search`, empty_search_result: (type: string) => `No ${type} match your search`,
search_objects: { search_objects: {

View File

@ -56,6 +56,7 @@ export const FEATURE_FLAG = {
license_multi_org_enabled: "license_multi_org_enabled", license_multi_org_enabled: "license_multi_org_enabled",
release_table_custom_sort_function_enabled: release_table_custom_sort_function_enabled:
"release_table_custom_sort_function_enabled", "release_table_custom_sort_function_enabled",
release_git_package_enabled: "release_git_package_enabled",
} as const; } as const;
export type FeatureFlag = keyof typeof FEATURE_FLAG; export type FeatureFlag = keyof typeof FEATURE_FLAG;
@ -103,6 +104,7 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = {
release_table_infinitescroll_enabled: false, release_table_infinitescroll_enabled: false,
license_multi_org_enabled: false, license_multi_org_enabled: false,
release_table_custom_sort_function_enabled: false, release_table_custom_sort_function_enabled: false,
release_git_package_enabled: false,
}; };
export const AB_TESTING_EVENT_KEYS = { export const AB_TESTING_EVENT_KEYS = {

View File

@ -29,7 +29,7 @@ export const OPS_MODAL = {
}; };
export const TAB_RELEASE = { export const TAB_RELEASE = {
TITLE: "Release version", TITLE: "Release a new version",
RELEASE_BTN: "Release", RELEASE_BTN: "Release",
}; };
@ -44,6 +44,7 @@ export const RELEASE_NOTES_INPUT = {
}; };
export const LATEST_COMMIT_INFO = { export const LATEST_COMMIT_INFO = {
TITLE: "Commit",
LOADING_COMMIT_MESSAGE: "Fetching latest commit...", LOADING_COMMIT_MESSAGE: "Fetching latest commit...",
NO_COMMIT_MESSAGE: "No commit message found", NO_COMMIT_MESSAGE: "No commit message found",
}; };

View File

@ -4,9 +4,16 @@ import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { howMuchTimeBeforeText } from "utils/helpers"; import { howMuchTimeBeforeText } from "utils/helpers";
const Container = styled(Flex)` const TitleText = styled(Text)`
border-radius: 4px; font-weight: 500;
background-color: var(--ads-v2-color-gray-0); `;
const MutedText = styled(Text)`
font-weight: 300;
`;
const LoadingContainer = styled(Flex)`
margin-bottom: 19px;
`; `;
interface LatestCommitInfoViewProps { interface LatestCommitInfoViewProps {
@ -28,29 +35,33 @@ function LatestCommitInfoView({
? howMuchTimeBeforeText(new Date(committedAt * 1000).toString()) ? howMuchTimeBeforeText(new Date(committedAt * 1000).toString())
: null; : null;
if (isLoading) {
return ( return (
<Container <Flex flexDirection="column" gap="spaces-3" marginBottom="spaces-6">
<TitleText data-testid="t--git-release-version-title" renderAs="p">
{LATEST_COMMIT_INFO.TITLE}
</TitleText>
{isLoading && (
<LoadingContainer
alignItems="center" alignItems="center"
data-testid="t--git-latest-commit-loading" data-testid="t--git-latest-commit-loading"
gap="spaces-3" gap="spaces-3"
marginBottom="spaces-4"
padding="spaces-3"
> >
<Spinner size="md" /> <Spinner size="md" />
<Text renderAs="p">{LATEST_COMMIT_INFO.LOADING_COMMIT_MESSAGE}</Text> <Text renderAs="p">{LATEST_COMMIT_INFO.LOADING_COMMIT_MESSAGE}</Text>
</Container> </LoadingContainer>
); )}
} {!isLoading && (
<Flex>
return ( <Flex flex={1} flexDirection="column" gap="spaces-2">
<Container marginBottom="spaces-4" padding="spaces-3"> <Text
<Flex flex={1} flexDirection="column" gap="spaces-3"> data-testid="t--git-latest-commit-message"
<Text data-testid="t--git-latest-commit-message" renderAs="p"> kind="body-s"
renderAs="p"
>
{message ?? <em>{LATEST_COMMIT_INFO.NO_COMMIT_MESSAGE}</em>} {message ?? <em>{LATEST_COMMIT_INFO.NO_COMMIT_MESSAGE}</em>}
</Text> </Text>
{authorName && ( {authorName && (
<Text <MutedText
data-testid="t--git-latest-commit-commited-by" data-testid="t--git-latest-commit-commited-by"
kind="body-s" kind="body-s"
renderAs="p" renderAs="p"
@ -61,18 +72,24 @@ function LatestCommitInfoView({
{authorName && readableCommittedAt {authorName && readableCommittedAt
? `${authorName} committed ${readableCommittedAt} ago` ? `${authorName} committed ${readableCommittedAt} ago`
: null} : null}
</Text> </MutedText>
)} )}
</Flex> </Flex>
<Flex alignItems="center" justifyContent="center"> <Flex alignItems="center" justifyContent="center">
<Flex gap="spaces-2"> <Flex gap="spaces-2">
<Icon name="git-commit" size="md" /> <Icon name="git-commit" size="md" />
<Text data-testid="t--git-latest-commit-hash" renderAs="p"> <MutedText
data-testid="t--git-latest-commit-hash"
kind="body-s"
renderAs="p"
>
{hash ?? "-"} {hash ?? "-"}
</Text> </MutedText>
</Flex> </Flex>
</Flex> </Flex>
</Container> </Flex>
)}
</Flex>
); );
} }

View File

@ -42,7 +42,7 @@ function TabReleaseView({
const [releaseVersion, setReleaseVersion] = useState<string | null>(null); const [releaseVersion, setReleaseVersion] = useState<string | null>(null);
const [releaseNotes, setReleaseNotes] = useState<string | null>(null); const [releaseNotes, setReleaseNotes] = useState<string | null>(null);
const isReleaseDisabled = !releaseVersion || !releaseNotes; const isReleaseDisabled = !releaseVersion;
useEffect( useEffect(
function fetchPretagOnInitEffect() { function fetchPretagOnInitEffect() {

View File

@ -4,7 +4,6 @@ import ReleaseVersionRadioGroupView from "./ReleaseVersionRadioGroupView";
import "@testing-library/jest-dom"; import "@testing-library/jest-dom";
describe("ReleaseVersionRadioGroupView", () => { describe("ReleaseVersionRadioGroupView", () => {
const releasedAt = Math.floor((Date.now() - 3600000) / 1000);
const mockOnVersionChange = jest.fn(); const mockOnVersionChange = jest.fn();
const renderComponent = (props = {}) => { const renderComponent = (props = {}) => {
@ -12,7 +11,6 @@ describe("ReleaseVersionRadioGroupView", () => {
<ReleaseVersionRadioGroupView <ReleaseVersionRadioGroupView
latestReleaseVersion="v1.0.0" latestReleaseVersion="v1.0.0"
onVersionChange={mockOnVersionChange} onVersionChange={mockOnVersionChange}
releasedAt={releasedAt}
{...props} {...props}
/>, />,
); );
@ -31,9 +29,6 @@ describe("ReleaseVersionRadioGroupView", () => {
expect(getByTestId("t--git-release-next-version").textContent).toBe( expect(getByTestId("t--git-release-next-version").textContent).toBe(
"v1.0.1", "v1.0.1",
); );
expect(getByTestId("t--git-release-released-at").textContent).toBe(
"Last released: v1.0.0 (1 hr ago)",
);
expect(getByRole("radio", { name: /patch/i })).toBeChecked(); expect(getByRole("radio", { name: /patch/i })).toBeChecked();
}); });

View File

@ -1,29 +1,36 @@
import React, { useCallback, useEffect, useMemo, useState } from "react"; import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Flex, Radio, RadioGroup, Tag, Text } from "@appsmith/ads"; import { Flex, Icon, Radio, RadioGroup, Tag, Text } from "@appsmith/ads";
import { RELEASE_VERSION_RADIO_GROUP } from "git/ee/constants/messages"; import { RELEASE_VERSION_RADIO_GROUP } from "git/ee/constants/messages";
import { inc } from "semver"; import { inc } from "semver";
import noop from "lodash/noop"; import noop from "lodash/noop";
import { howMuchTimeBeforeText } from "utils/helpers"; import styled from "styled-components";
const TitleText = styled(Text)`
font-weight: 500;
`;
const CurrentVersionTag = styled(Tag)`
border-color: var(--ads-v2-color-gray-300);
`;
const NextVersionTag = styled(Tag)`
background-color: var(--ads-v2-color-purple-100);
border-color: var(--ads-v2-color-purple-300);
`;
type ReleaseType = "major" | "minor" | "patch" | null; type ReleaseType = "major" | "minor" | "patch" | null;
interface ReleaseVersionRadioGroupViewProps { interface ReleaseVersionRadioGroupViewProps {
latestReleaseVersion: string | null; latestReleaseVersion: string | null;
onVersionChange: (value: string | null) => void; onVersionChange: (value: string | null) => void;
releasedAt: number | null;
} }
function ReleaseVersionRadioGroupView({ function ReleaseVersionRadioGroupView({
latestReleaseVersion = null, latestReleaseVersion = null,
onVersionChange = noop, onVersionChange = noop,
releasedAt = null,
}: ReleaseVersionRadioGroupViewProps) { }: ReleaseVersionRadioGroupViewProps) {
const [releaseType, setReleaseType] = useState<ReleaseType>("patch"); const [releaseType, setReleaseType] = useState<ReleaseType>("patch");
const readableReleaseAt = releasedAt
? howMuchTimeBeforeText(new Date(releasedAt * 1000).toString())
: null;
const nextVersion = useMemo(() => { const nextVersion = useMemo(() => {
if (!releaseType) return null; if (!releaseType) return null;
@ -47,20 +54,10 @@ function ReleaseVersionRadioGroupView({
}, []); }, []);
return ( return (
<Flex flexDirection="column" gap="spaces-2" marginBottom="spaces-4"> <Flex flexDirection="column" gap="spaces-3" marginBottom="spaces-4">
<Text data-testid="t--git-release-version-title" renderAs="p"> <TitleText data-testid="t--git-release-version-title" renderAs="p">
{RELEASE_VERSION_RADIO_GROUP.TITLE} {RELEASE_VERSION_RADIO_GROUP.TITLE}
</Text> </TitleText>
<Flex alignItems="center" gap="spaces-4">
<Flex minWidth="40px">
<Tag
data-testid="t--git-release-next-version"
isClosable={false}
kind="neutral"
>
{nextVersion ?? "-"}
</Tag>
</Flex>
<RadioGroup <RadioGroup
UNSAFE_gap="var(--ads-v2-spaces-4)" UNSAFE_gap="var(--ads-v2-spaces-4)"
onChange={handleRadioChange} onChange={handleRadioChange}
@ -71,18 +68,28 @@ function ReleaseVersionRadioGroupView({
<Radio value="minor">Minor</Radio> <Radio value="minor">Minor</Radio>
<Radio value="patch">Patch</Radio> <Radio value="patch">Patch</Radio>
</RadioGroup> </RadioGroup>
</Flex> <Flex gap="spaces-2">
{latestReleaseVersion && ( {latestReleaseVersion && (
<Text <CurrentVersionTag
data-testid="t--git-release-released-at" data-testid="t--git-release-current-version"
kind="body-s" isClosable={false}
renderAs="p" kind="neutral"
> >
{RELEASE_VERSION_RADIO_GROUP.LAST_RELEASED}:{" "} {latestReleaseVersion}
{latestReleaseVersion ?? "-"}{" "} </CurrentVersionTag>
{readableReleaseAt ? `(${readableReleaseAt} ago)` : null}
</Text>
)} )}
{latestReleaseVersion && nextVersion && (
<Icon name="arrow-right-line" size="sm" />
)}
<NextVersionTag
color="var(--ads-v2-color-purple-100)"
data-testid="t--git-release-next-version"
isClosable={false}
kind="neutral"
>
{nextVersion ?? "-"}
</NextVersionTag>
</Flex>
</Flex> </Flex>
); );
} }

View File

@ -16,7 +16,6 @@ function ReleaseVersionRadioGroup({
<ReleaseVersionRadioGroupView <ReleaseVersionRadioGroupView
latestReleaseVersion={pretagResponse?.releaseTagName ?? null} latestReleaseVersion={pretagResponse?.releaseTagName ?? null}
onVersionChange={onVersionChange} onVersionChange={onVersionChange}
releasedAt={pretagResponse?.releasedAt ?? null}
/> />
); );
} }