Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: DIA-1794: [FE] Home page (+Tailwind and shadcn integration) #7009

Merged
merged 44 commits into from
Mar 6, 2025
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
0cc2de8
Revert "chore: Reverts tailwind and LSO Homepage (#7007)"
nick-skriabin Feb 3, 2025
6d8ecf5
Update feature flag check
nick-skriabin Feb 3, 2025
7ae1a73
Merge branch 'develop' into fb-dia-1783/tailwind-next
nick-skriabin Feb 4, 2025
daf2f14
Megre
nick-skriabin Feb 12, 2025
1989fe4
Deps
nick-skriabin Feb 13, 2025
614b16e
Merge branch 'develop' into fb-dia-1783/tailwind-next
nick-skriabin Feb 14, 2025
6b41956
Merge branch 'develop' into fb-dia-1783/tailwind-next
nick-skriabin Feb 20, 2025
826721f
Merge branch 'develop' into fb-dia-1783/tailwind-next
nick-skriabin Feb 20, 2025
2922317
Fix antd situation
nick-skriabin Feb 20, 2025
51e34e8
Update imports to be more uniform
nick-skriabin Feb 21, 2025
1cab918
Remove excess
nick-skriabin Feb 21, 2025
2a435a7
Fix home page and user account page
nick-skriabin Feb 21, 2025
d9cd924
Fix buttons style
nick-skriabin Feb 24, 2025
36569a9
Fix space alignment, fix text sizing
nick-skriabin Feb 24, 2025
cb4cc3e
Add missing BG color
nick-skriabin Feb 24, 2025
bc6a3b6
Add colors
nick-skriabin Feb 24, 2025
eb88dba
Fix feature flag
nick-skriabin Feb 25, 2025
9746b06
Fix people page
nick-skriabin Feb 25, 2025
ccb89b8
Remove models button, fix padding
nick-skriabin Feb 25, 2025
5cc3edc
Fix labels input padding
nick-skriabin Feb 25, 2025
f58a027
Fix labels alignment
nick-skriabin Feb 26, 2025
3bb07c7
Fix button sizing
nick-skriabin Feb 26, 2025
2382165
Make entire project card clickable
nick-skriabin Feb 26, 2025
48f0717
Fix silent error
nick-skriabin Feb 26, 2025
6524722
Fix button style
nick-skriabin Feb 27, 2025
97c61f6
Allow per-user flag check
nick-skriabin Feb 27, 2025
da0a1d9
Fix UI issues
nick-skriabin Feb 28, 2025
4e83d80
Fix counters
nick-skriabin Feb 28, 2025
bb6ad82
Fix paddings and UI
nick-skriabin Mar 3, 2025
15d1a33
Fix buttons
nick-skriabin Mar 3, 2025
3b8d16e
Merge branch 'develop' into fb-dia-1783/tailwind-next
nick-skriabin Mar 3, 2025
062231a
Fix import
nick-skriabin Mar 3, 2025
15e9dbb
Update imports
nick-skriabin Mar 3, 2025
bfdd5f7
Update filename
nick-skriabin Mar 4, 2025
a80ba7c
Change casing -- spinner
nick-skriabin Mar 4, 2025
6747eb6
Change casing -- space
nick-skriabin Mar 4, 2025
b32ed86
Fix export
nick-skriabin Mar 4, 2025
a315d55
Remove excess file
nick-skriabin Mar 4, 2025
d734ffb
Update web/apps/labelstudio/src/components/Modal/ModalPopup.jsx
nick-skriabin Mar 4, 2025
eec5871
Update web/apps/labelstudio/src/pages/Organization/PeoplePage/InviteL…
nick-skriabin Mar 4, 2025
72ae90d
Remove excess
nick-skriabin Mar 4, 2025
60bdf1b
Fix import
nick-skriabin Mar 4, 2025
1f44b51
Merge branch 'develop' into fb-dia-1783/tailwind-next
nick-skriabin Mar 5, 2025
22506cd
Merge branch 'develop' into 'fb-dia-1783/tailwind-next'
bmartel Mar 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions Dockerfile.development
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# syntax=docker/dockerfile:1
ARG NODE_VERSION=18
ARG PYTHON_VERSION=3.12
ARG POETRY_VERSION=2.0.1
ARG VERSION_OVERRIDE
ARG BRANCH_OVERRIDE

################################ Overview

# This Dockerfile builds a Label Studio environment.
# It consists of three main stages:
# 1. "frontend-builder" - Compiles the frontend assets using Node.
# 2. "frontend-version-generator" - Generates version files for frontend sources.
# 3. "venv-builder" - Prepares the virtualenv environment.
# 4. "py-version-generator" - Generates version files for python sources.
# 5. "prod" - Creates the final production image with the Label Studio, Nginx, and other dependencies.

################################ Stage: frontend-builder (build frontend assets)
FROM --platform=${BUILDPLATFORM} node:${NODE_VERSION} AS frontend-builder
WORKDIR /label-studio/web

COPY web .
COPY pyproject.toml ../pyproject.toml

################################ Stage: venv-builder (prepare the virtualenv)
FROM python:${PYTHON_VERSION}-slim AS venv-builder
ARG POETRY_VERSION

ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100 \
PIP_CACHE_DIR="/.cache" \
POETRY_CACHE_DIR="/.poetry-cache" \
POETRY_HOME="/opt/poetry" \
POETRY_VIRTUALENVS_IN_PROJECT=true \
PATH="/opt/poetry/bin:$PATH"

ADD https://install.python-poetry.org /tmp/install-poetry.py
RUN python /tmp/install-poetry.py

RUN --mount=type=cache,target="/var/cache/apt",sharing=locked \
--mount=type=cache,target="/var/lib/apt/lists",sharing=locked \
set -eux; \
apt-get update; \
apt-get install --no-install-recommends -y \
build-essential git; \
apt-get autoremove -y

WORKDIR /label-studio

ENV VENV_PATH="/label-studio/.venv"
ENV PATH="$VENV_PATH/bin:$PATH"

## Starting from this line all packages will be installed in $VENV_PATH

# Copy dependency files
COPY pyproject.toml poetry.lock README.md ./

# Install dependencies without dev packages
RUN --mount=type=cache,target=$POETRY_CACHE_DIR,sharing=locked \
poetry check --lock && poetry install --no-root --without test --extras uwsgi

# Install LS
COPY label_studio label_studio
RUN --mount=type=cache,target=$POETRY_CACHE_DIR,sharing=locked \
# `--extras uwsgi` is mandatory here due to poetry bug: https://github.com/python-poetry/poetry/issues/7302
poetry install --only-root --extras uwsgi && \
python3 label_studio/manage.py collectstatic --no-input

################################ Stage: py-version-generator
FROM venv-builder AS py-version-generator
ARG VERSION_OVERRIDE
ARG BRANCH_OVERRIDE

# Create version_.py and ls-version_.py
RUN --mount=type=bind,source=.git,target=./.git \
VERSION_OVERRIDE=${VERSION_OVERRIDE} BRANCH_OVERRIDE=${BRANCH_OVERRIDE} poetry run python label_studio/core/version.py

################################### Stage: prod
FROM python:${PYTHON_VERSION}-slim AS production

ENV LS_DIR=/label-studio \
HOME=/label-studio \
LABEL_STUDIO_BASE_DATA_DIR=/label-studio/data \
OPT_DIR=/opt/heartex/instance-data/etc \
PATH="/label-studio/.venv/bin:$PATH" \
DJANGO_SETTINGS_MODULE=core.settings.label_studio \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1

WORKDIR $LS_DIR

# install prerequisites for app
RUN --mount=type=cache,target="/var/cache/apt",sharing=locked \
--mount=type=cache,target="/var/lib/apt/lists",sharing=locked \
set -eux; \
apt-get update; \
apt-get upgrade -y; \
apt-get install --no-install-recommends -y libexpat1 \
gnupg2 curl; \
apt-get autoremove -y

# install nginx
RUN --mount=type=cache,target="/var/cache/apt",sharing=locked \
--mount=type=cache,target="/var/lib/apt/lists",sharing=locked \
set -eux; \
curl -sSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor -o /etc/apt/keyrings/nginx-archive-keyring.gpg >/dev/null; \
DEBIAN_VERSION=$(awk -F '=' '/^VERSION_CODENAME=/ {print $2}' /etc/os-release); \
printf "deb [signed-by=/etc/apt/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian ${DEBIAN_VERSION} nginx\n" > /etc/apt/sources.list.d/nginx.list; \
printf "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" > /etc/apt/preferences.d/99nginx; \
apt-get update; \
apt-get install --no-install-recommends -y nginx; \
apt-get autoremove -y

RUN set -eux; \
mkdir -p $LS_DIR $LABEL_STUDIO_BASE_DATA_DIR $OPT_DIR && \
chown -R 1001:0 $LS_DIR $LABEL_STUDIO_BASE_DATA_DIR $OPT_DIR /var/log/nginx /etc/nginx

COPY --chown=1001:0 deploy/default.conf /etc/nginx/nginx.conf

# Copy essential files for installing Label Studio and its dependencies
COPY --chown=1001:0 pyproject.toml .
COPY --chown=1001:0 poetry.lock .
COPY --chown=1001:0 README.md .
COPY --chown=1001:0 LICENSE LICENSE
COPY --chown=1001:0 licenses licenses
COPY --chown=1001:0 deploy deploy

# Copy files from build stages
COPY --chown=1001:0 --from=venv-builder $LS_DIR $LS_DIR
COPY --chown=1001:0 --from=py-version-generator $LS_DIR/label_studio/core/version_.py $LS_DIR/label_studio/core/version_.py
COPY --chown=1001:0 --from=frontend-builder $LS_DIR/web/dist $LS_DIR/web/dist

USER 1001

EXPOSE 8080

ENTRYPOINT ["./deploy/docker-entrypoint.sh"]
CMD ["label-studio"]
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ docker-run-dev:
docker-migrate-dev:
docker compose run app python3 /label-studio/label_studio/manage.py migrate

docker-collectstatic-dev:
docker compose run app python3 /label-studio/label_studio/manage.py collectstatic

# Install modules
frontend-install:
cd web && yarn install --frozen-lockfile;
Expand Down
3 changes: 3 additions & 0 deletions label_studio/core/templates/home/home.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{% extends 'base.html' %}
{% load i18n %}
{% load static %}
10 changes: 7 additions & 3 deletions label_studio/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import pandas as pd
import requests
from core import utils
from core.feature_flags import all_flags, get_feature_file_path
from core.feature_flags import all_flags, flag_set, get_feature_file_path
from core.label_config import generate_time_series_json
from core.utils.common import collect_versions
from core.utils.io import find_file
Expand All @@ -27,7 +27,7 @@
HttpResponseServerError,
JsonResponse,
)
from django.shortcuts import redirect, reverse
from django.shortcuts import redirect, render, reverse
from django.template import loader
from django.utils._os import safe_join
from django.views.decorators.csrf import csrf_exempt
Expand Down Expand Up @@ -55,7 +55,11 @@
return redirect(reverse('user-login'))

# business mode access
return redirect(reverse('projects:project-index'))
if flag_set('fflag_all_feat_dia_1777_ls_homepage_short', user):
print('redirect to home page')
return render(request, 'home/home.html')

Check warning on line 60 in label_studio/core/views.py

View check run for this annotation

Codecov / codecov/patch

label_studio/core/views.py#L58-L60

Added lines #L58 - L60 were not covered by tests
else:
return redirect(reverse('projects:project-index'))

Check warning on line 62 in label_studio/core/views.py

View check run for this annotation

Codecov / codecov/patch

label_studio/core/views.py#L62

Added line #L62 was not covered by tests

# not authenticated
return redirect(reverse('user-login'))
Expand Down
2 changes: 1 addition & 1 deletion label_studio/users/templates/users/user_account.html
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@
<div class="field field--wide">
<label for="example_fetch">Example fetch projects data:</label>
<textarea id="example_fetch" class="example_code ls-textarea" type="text" readonly
style="height: 92px; font-size: 14px">
style="height: 92px; font-size: 14px; padding: 9px 16px">
{% if settings.HOSTNAME %}
curl -X GET {{ settings.HOSTNAME }}/api/projects/ -H 'Authorization: Token {{token}}'
{% else %}
Expand Down
10 changes: 8 additions & 2 deletions label_studio/users/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@

# checks if the URL is a safe redirection.
if not next_page or not url_has_allowed_host_and_scheme(url=next_page, allowed_hosts=request.get_host()):
next_page = reverse('projects:project-index')
if flag_set('fflag_all_feat_dia_1777_ls_homepage_short', user):
next_page = reverse('main')

Check warning on line 49 in label_studio/users/views.py

View check run for this annotation

Codecov / codecov/patch

label_studio/users/views.py#L49

Added line #L49 was not covered by tests
else:
next_page = reverse('projects:project-index')

user_form = forms.UserSignupForm()
organization_form = OrganizationSignupForm()
Expand Down Expand Up @@ -105,7 +108,10 @@

# checks if the URL is a safe redirection.
if not next_page or not url_has_allowed_host_and_scheme(url=next_page, allowed_hosts=request.get_host()):
next_page = reverse('projects:project-index')
if flag_set('fflag_all_feat_dia_1777_ls_homepage_short', user):
next_page = reverse('main')

Check warning on line 112 in label_studio/users/views.py

View check run for this annotation

Codecov / codecov/patch

label_studio/users/views.py#L112

Added line #L112 was not covered by tests
else:
next_page = reverse('projects:project-index')

login_form = load_func(settings.USER_LOGIN_FORM)
form = login_form()
Expand Down
1 change: 1 addition & 0 deletions web/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ tmp

# dependencies
node_modules
dist

# IDEs and editors
/.idea
Expand Down
4 changes: 3 additions & 1 deletion web/.stylelintrc.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
{
"extends": "stylelint-config-standard-scss",
"extends": ["stylelint-config-tailwindcss/scss", "stylelint-config-standard-scss"],
"rules": {
"selector-class-pattern": null,
"custom-property-pattern": null,
"no-descending-specificity": null,
"function-no-unknown": null,
"scss/no-global-function-names": null,
"scss/function-no-unknown": null,
"selector-pseudo-class-no-unknown": [
true,
{
Expand Down
16 changes: 14 additions & 2 deletions web/apps/labelstudio/src/app/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,27 @@ import { MultiProvider } from "../providers/MultiProvider";
import { ProjectProvider } from "../providers/ProjectProvider";
import { RoutesProvider } from "../providers/RoutesProvider";
import { DRAFT_GUARD_KEY, DraftGuard, draftGuardCallback } from "../components/DraftGuard/DraftGuard";
import "./App.scss";
import { AsyncPage } from "./AsyncPage/AsyncPage";
import ErrorBoundary from "./ErrorBoundary";
import { RootPage } from "./RootPage";
import { FF_OPTIC_2, FF_UNSAVED_CHANGES, FF_PRODUCT_TOUR, isFF } from "../utils/feature-flags";
import { TourProvider } from "@humansignal/core";
import { ToastProvider, ToastViewport } from "@humansignal/ui";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { JotaiProvider, JotaiStore } from "../utils/jotai-store";
import { CurrentUserProvider } from "../providers/CurrentUser";
import { RootPage } from "./RootPage";
import "@humansignal/ui/src/tailwind.css";
import "./App.scss";

const baseURL = new URL(APP_SETTINGS.hostname || location.origin);
export const UNBLOCK_HISTORY_MESSAGE = "UNBLOCK_HISTORY";
const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
},
},
});

const browserHistory = createBrowserHistory({
basename: baseURL.pathname || "/",
Expand Down Expand Up @@ -57,6 +67,8 @@ const App = ({ content }) => {
<Router history={browserHistory}>
<MultiProvider
providers={[
<JotaiProvider key="jotai" store={JotaiStore} />,
<QueryClientProvider key="query" client={queryClient} />,
<AppStoreProvider key="app-store" />,
<ApiProvider key="api" />,
<ConfigProvider key="config" />,
Expand Down
3 changes: 2 additions & 1 deletion web/apps/labelstudio/src/components/Button/Button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
border: var(--button-border);
cursor: pointer;
outline: none;
flex-shrink: 0;
display: inline-flex;
text-align: center;
transition: all 100ms ease;
Expand Down Expand Up @@ -360,4 +361,4 @@
100% {
background-position: 37px 0;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@
opacity: 0.5;
top: 1px;
position: relative;
}
display: inline;
vertical-align: baseline;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { clsx } from "clsx";
/** @deprecated - needs to be replaced with @humansignal/ui Label - visualizes differently currently */
const Label = ({ text, children, required, placement, description, size, large, style, simple, flat, className }) => {
const rootClass = cn("label-ls");
const classList = [rootClass];
const classList = [rootClass.toClassName()];
const tagName = simple ? "div" : "label";
const mods = {
size,
Expand Down
16 changes: 8 additions & 8 deletions web/apps/labelstudio/src/components/Menubar/Menubar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { StaticContent } from "../../app/StaticContent/StaticContent";
import {
IconBook,
IconFolder,
IconModel,
IconPersonInCircle,
IconPin,
IconTerminal,
Expand All @@ -26,9 +25,10 @@ import { VersionNotifier, VersionProvider } from "../VersionNotifier/VersionNoti
import "./Menubar.scss";
import "./MenuContent.scss";
import "./MenuSidebar.scss";
import { ModelsPage } from "../../pages/Organization/Models/ModelsPage";
import { FF_DIA_835, isFF } from "../../utils/feature-flags";
import { AccountSettingsPage } from "@humansignal/core";
import { FF_HOMEPAGE } from "../../utils/feature-flags";
import { IconHome } from "@humansignal/ui";
import { pages } from "@humansignal/core";
import { isFF } from "../../utils/feature-flags";

export const MenubarContext = createContext();

Expand Down Expand Up @@ -135,7 +135,7 @@ export const Menubar = ({ enabled, defaultOpened, defaultPinned, children, onSid
<div className={menubarClass}>
<Dropdown.Trigger dropdown={menuDropdownRef} closeOnClickOutside={!sidebarPinned}>
<div className={`${menubarClass.elem("trigger")} main-menu-trigger`}>
<img src={absoluteURL("/static/icons/logo.svg")} alt="Label Studio Logo" height="22" />
<img src={absoluteURL("/static/icons/logo.svg")} alt="Label Studio Logo" style={{ height: 22 }} />
<Hamburger opened={sidebarOpened} />
</div>
</Dropdown.Trigger>
Expand All @@ -151,13 +151,13 @@ export const Menubar = ({ enabled, defaultOpened, defaultPinned, children, onSid
align="right"
content={
<Menu>
<Menu.Item icon={<LsSettings />} label="Account &amp; Settings" href={AccountSettingsPage.path} />
<Menu.Item icon={<LsSettings />} label="Account &amp; Settings" href={pages.AccountSettingsPage.path} />
{/* <Menu.Item label="Dark Mode"/> */}
<Menu.Item icon={<LsDoor />} label="Log Out" href={absoluteURL("/logout")} data-external />
{showNewsletterDot && (
<>
<Menu.Divider />
<Menu.Item className={cn("newsletter-menu-item")} href={AccountSettingsPage.path}>
<Menu.Item className={cn("newsletter-menu-item")} href={pages.AccountSettingsPage.path}>
<span>Please check new notification settings in the Account & Settings page</span>
<span className={cn("newsletter-menu-badge")} />
</Menu.Item>
Expand Down Expand Up @@ -186,9 +186,9 @@ export const Menubar = ({ enabled, defaultOpened, defaultPinned, children, onSid
style={{ width: 240 }}
>
<Menu>
{isFF(FF_HOMEPAGE) && <Menu.Item label="Home" to="/" icon={<IconHome />} data-external exact />}
<Menu.Item label="Projects" to="/projects" icon={<IconFolder />} data-external exact />
<Menu.Item label="Organization" to="/organization" icon={<IconPersonInCircle />} data-external exact />
{isFF(FF_DIA_835) && <Menu.Item label="Models" to={ModelsPage.path} icon={<IconModel />} exact />}

<Menu.Spacer />

Expand Down
Loading
Loading