diff --git a/Dockerfile.development b/Dockerfile.development deleted file mode 100644 index e1b89c13497d..000000000000 --- a/Dockerfile.development +++ /dev/null @@ -1,141 +0,0 @@ -# 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"] diff --git a/Makefile b/Makefile index d1a8f067d5a7..5ea66738f281 100644 --- a/Makefile +++ b/Makefile @@ -33,9 +33,6 @@ 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; diff --git a/label_studio/core/templates/home/home.html b/label_studio/core/templates/home/home.html deleted file mode 100644 index 3d19a4ecfce8..000000000000 --- a/label_studio/core/templates/home/home.html +++ /dev/null @@ -1,3 +0,0 @@ -{% extends 'base.html' %} -{% load i18n %} -{% load static %} diff --git a/label_studio/core/views.py b/label_studio/core/views.py index dd737f02892d..7c048a19e8ea 100644 --- a/label_studio/core/views.py +++ b/label_studio/core/views.py @@ -13,7 +13,7 @@ import pandas as pd import requests from core import utils -from core.feature_flags import all_flags, flag_set, get_feature_file_path +from core.feature_flags import all_flags, 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 @@ -27,7 +27,7 @@ HttpResponseServerError, JsonResponse, ) -from django.shortcuts import redirect, render, reverse +from django.shortcuts import redirect, reverse from django.template import loader from django.utils._os import safe_join from django.views.decorators.csrf import csrf_exempt @@ -55,10 +55,7 @@ def main(request): return redirect(reverse('user-login')) # business mode access - if flag_set('fflag_all_feat_dia_1777_ls_homepage_short'): - return render(request, 'home/home.html') - else: - return redirect(reverse('projects:project-index')) + return redirect(reverse('projects:project-index')) # not authenticated return redirect(reverse('user-login')) diff --git a/label_studio/users/views.py b/label_studio/users/views.py index 52b1f5f76062..77ea4edcb4c0 100644 --- a/label_studio/users/views.py +++ b/label_studio/users/views.py @@ -41,10 +41,7 @@ def user_signup(request): # 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()): - if flag_set('fflag_all_feat_dia_1777_ls_homepage_short'): - next_page = reverse('main') - else: - next_page = reverse('projects:project-index') + next_page = reverse('projects:project-index') user_form = forms.UserSignupForm() organization_form = OrganizationSignupForm() @@ -104,10 +101,7 @@ def user_login(request): # 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()): - if flag_set('fflag_all_feat_dia_1777_ls_homepage_short'): - next_page = reverse('main') - else: - next_page = reverse('projects:project-index') + next_page = reverse('projects:project-index') login_form = load_func(settings.USER_LOGIN_FORM) form = login_form() diff --git a/web/.gitignore b/web/.gitignore index aa895eebf506..826c9d84514f 100644 --- a/web/.gitignore +++ b/web/.gitignore @@ -6,7 +6,6 @@ tmp # dependencies node_modules -dist # IDEs and editors /.idea diff --git a/web/.stylelintrc.json b/web/.stylelintrc.json index f85d1a259049..b14abcd5a139 100644 --- a/web/.stylelintrc.json +++ b/web/.stylelintrc.json @@ -1,12 +1,10 @@ { - "extends": ["stylelint-config-tailwindcss/scss", "stylelint-config-standard-scss"], + "extends": "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, { diff --git a/web/apps/labelstudio/src/app/App.jsx b/web/apps/labelstudio/src/app/App.jsx index efbde5452813..7eeb45e658de 100644 --- a/web/apps/labelstudio/src/app/App.jsx +++ b/web/apps/labelstudio/src/app/App.jsx @@ -19,19 +19,9 @@ 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 "@humansignal/ui/src/tailwind.css"; -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { JotaiProvider, JotaiStore } from "../utils/jotai-store"; 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 || "/", @@ -66,8 +56,6 @@ const App = ({ content }) => { , - , , , , diff --git a/web/apps/labelstudio/src/components/DescriptionList/DescriptionList.scss b/web/apps/labelstudio/src/components/DescriptionList/DescriptionList.scss index c883f951c3d8..4bb2d13356ad 100644 --- a/web/apps/labelstudio/src/components/DescriptionList/DescriptionList.scss +++ b/web/apps/labelstudio/src/components/DescriptionList/DescriptionList.scss @@ -21,6 +21,4 @@ opacity: 0.5; top: 1px; position: relative; - display: inline; - vertical-align: baseline; -} +} \ No newline at end of file diff --git a/web/apps/labelstudio/src/components/Menubar/Menubar.jsx b/web/apps/labelstudio/src/components/Menubar/Menubar.jsx index 4ace04b8bad7..7f13680a47fe 100644 --- a/web/apps/labelstudio/src/components/Menubar/Menubar.jsx +++ b/web/apps/labelstudio/src/components/Menubar/Menubar.jsx @@ -26,8 +26,7 @@ import "./Menubar.scss"; import "./MenuContent.scss"; import "./MenuSidebar.scss"; import { ModelsPage } from "../../pages/Organization/Models/ModelsPage"; -import { FF_DIA_835, FF_HOMEPAGE, isFF } from "../../utils/feature-flags"; -import { IconHome } from "@humansignal/ui"; +import { FF_DIA_835, isFF } from "../../utils/feature-flags"; export const MenubarContext = createContext(); @@ -133,7 +132,7 @@ export const Menubar = ({ enabled, defaultOpened, defaultPinned, children, onSid
- Label Studio Logo + Label Studio Logo
@@ -184,7 +183,6 @@ export const Menubar = ({ enabled, defaultOpened, defaultPinned, children, onSid style={{ width: 240 }} > - {isFF(FF_HOMEPAGE) && } data-external exact />} } data-external exact /> } data-external exact /> {isFF(FF_DIA_835) && } exact />} diff --git a/web/apps/labelstudio/src/components/Modal/ModalPopup.jsx b/web/apps/labelstudio/src/components/Modal/ModalPopup.jsx index c9b88d3cd128..f120bf3bc892 100644 --- a/web/apps/labelstudio/src/components/Modal/ModalPopup.jsx +++ b/web/apps/labelstudio/src/components/Modal/ModalPopup.jsx @@ -204,8 +204,8 @@ Modal.Header = ({ children, divided }) => ( ); -Modal.Footer = ({ children, bare, style, className }) => ( - +Modal.Footer = ({ children, bare }) => ( + {children} ); diff --git a/web/apps/labelstudio/src/pages/CreateProject/Config/Config.jsx b/web/apps/labelstudio/src/pages/CreateProject/Config/Config.jsx index f0036e46bcb9..b2f0e2e468fb 100644 --- a/web/apps/labelstudio/src/pages/CreateProject/Config/Config.jsx +++ b/web/apps/labelstudio/src/pages/CreateProject/Config/Config.jsx @@ -105,10 +105,8 @@ const ConfigureControl = ({ control, template }) => {

{tagname === "Choices" ? "Add choices" : "Add label names"}

Use new line as a separator to add multiple labels -