diff --git a/Dockerfile.development b/Dockerfile.development new file mode 100644 index 000000000000..e1b89c13497d --- /dev/null +++ b/Dockerfile.development @@ -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"] diff --git a/Makefile b/Makefile index 5ea66738f281..d1a8f067d5a7 100644 --- a/Makefile +++ b/Makefile @@ -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; diff --git a/docs/themes/v2/source/css/codemirror.css b/docs/themes/v2/source/css/codemirror.css index e5e17d108e0c..70d29a709287 100644 --- a/docs/themes/v2/source/css/codemirror.css +++ b/docs/themes/v2/source/css/codemirror.css @@ -25,8 +25,8 @@ /* GUTTER */ .CodeMirror-gutters { - border-right: 1px solid #ddd; - background-color: #f7f7f7; + border-right: 1px solid var(--color-neutral-border); + background-color: var(--color-neutral-surface); white-space: nowrap; } .CodeMirror-linenumbers { @@ -43,13 +43,13 @@ color: black; } .CodeMirror-guttermarker-subtle { - color: #999; + color: var(--color-neutral-content-subtlest); } /* CURSOR */ .CodeMirror-cursor { - border-left: 1px solid black; + border-left: 1px solid var(--color-neutral-inverted-content); border-right: none; width: 0; } @@ -134,16 +134,16 @@ /* DEFAULT THEME */ .cm-s-default .cm-header { - color: #617ADA; + color: var(--color-accent-grape-bold); } .cm-s-default .cm-quote { - color: #34988D; + color: var(--color-accent-kale-bold); } .cm-negative { - color: #E6694E; + color: var(--color-negative-content); } .cm-positive { - color: #34988D; + color: var(--color-positive-content); } .cm-header, .cm-strong { @@ -181,16 +181,16 @@ } .cm-s-default .cm-variable-3, .cm-s-default .cm-type { - color: #34988D; + color: var(--color-accent-kale-bold); } .cm-s-default .cm-comment { - color: #E69559; + color: var(--color-accent-canteloupe-bold); } .cm-s-default .cm-string { - color: #CC6FBE; + color: var(--color-accent-plum-bold); } .cm-s-default .cm-string-2 { - color: #E6694E; + color: var(--color-accent-persimmon-bold); } .cm-s-default .cm-meta { color: #6B6860; @@ -218,10 +218,10 @@ } .cm-s-default .cm-error { - color: #E6694E; + color: var(--color-negative-content); } .cm-invalidchar { - color: #E6694E; + color: var(--color-negative-content); } .CodeMirror-composing { @@ -231,10 +231,10 @@ /* Default styles for common addons */ div.CodeMirror span.CodeMirror-matchingbracket { - color: #0b0; + color: var(--color-positive-content); } div.CodeMirror span.CodeMirror-nonmatchingbracket { - color: #a22; + color: var(--color-negative-content); } .CodeMirror-matchingtag { background: rgba(255, 150, 0, 0.3); @@ -251,7 +251,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket { .CodeMirror { position: relative; overflow: hidden; - background: white; + background: var(--color-neutral-background); } .CodeMirror-scroll { diff --git a/label_studio/core/static/css/login.css b/label_studio/core/static/css/login.css index 8a318311dc51..79f0a29fe749 100644 --- a/label_studio/core/static/css/login.css +++ b/label_studio/core/static/css/login.css @@ -7,6 +7,8 @@ html, body { font-weight: 400; height: 100%; font-family: 'Hellix', sans-serif; + background-color: var(--color-neutral-background-bold); + color: var(--color-neutral-content); } .login_page_new_ui .left { @@ -31,6 +33,18 @@ html, body { background-size: contain; } +.login_page_new_ui .ls-logo { + width: 414px; + height: 64px; + color: var(--color-neutral-content); +} + +.login_page_new_ui .hs-logo { + width: 152px; + height: 22px; + color: var(--color-neutral-content); +} + .login_page_new_ui .left h2 { font-size: 24px; font-weight: 500; @@ -48,7 +62,7 @@ html, body { margin: 8px 0 0 0; } -.login_page_new_ui .left .logo_humansignal{ +.login_page_new_ui .left .by { position: absolute; bottom: 60px; left: 60px; @@ -60,12 +74,16 @@ html, body { line-height: 28px; } +.login_page_new_ui .left img { + color: var(--color-neutral-content); +} + .login_page_new_ui .tips { max-width: 520px; border-radius: 8px; - border: 1px solid var(--sand_300); - background: var(--sand_0); - box-shadow: 0 2px 6px 0 var(--sand_300); + border: 1px solid var(--color-neutral-border); + background: var(--color-neutral-surface); + box-shadow: 0 2px 6px 0 rgb(var(--color-neutral-shadow) / 20%); padding: 16px; margin:18vh 60px 0 60px; position: relative; @@ -79,6 +97,7 @@ html, body { position: absolute; bottom: -72px; left: 16px; + fill: var(--color-neutral-border); background: url('../images/heidi-tip.svg') no-repeat center center; } @@ -100,7 +119,7 @@ html, body { } .login_page_new_ui .tips .description a { - color: var(--primary_link); + color: var(--color-primary-content); font-size: .875rem; font-style: normal; font-weight: 500; @@ -134,22 +153,23 @@ html, body { text-align: center; padding: .75rem 0; font-size: 1rem; - color: var(--sand_500); + color: var(--color-neutral-border); border-top: 2px solid transparent; + transition: all 150ms ease-out; } .login_page_new_ui .toggle > *.active { - border-color: var(--primary_link); - color: var(--primary_link); + border-color: var(--color-primary-surface); + color: var(--color-primary-content); } .login_page_new_ui .toggle > *:hover { - color: var(--grape_700); - border-color: var(--grape_700); + color: var(--color-primary-surface-hover); + border-color: var(--color-primary-surface-hover); } .form-wrapper{ position: relative; - background: #FDFDFC; + background: var(--color-neutral-surface); margin-top: 1.5rem; - border: 1px solid #E1DED5; + border: 1px solid var(--color-neutral-border); padding: 2rem; border-radius: 1rem; box-shadow: 0px 0px 12px rgba(23, 20, 13, 0.16); @@ -177,7 +197,7 @@ html, body { margin: 0; } .login_page_new_ui form .error { - color: var(--red_7); + color: var(--color-negative-content); font-size: .875rem; } .login_page_new_ui form input, @@ -187,9 +207,10 @@ html, body { font-family: 'Hellix', sans-serif; } -.login_page_new_ui form button { +.login_page_new_ui form .lsf-button-ls.lsf-button-ls_look_primary { + --button-color: var(--color-neutral-inverted-content); border-radius: 4rem; - background: var(--sand_900); + background: var(--color-neutral-inverted-surface); } .login_page_new_ui .field_errors { @@ -199,7 +220,7 @@ html, body { text-align: left; font-size: .875rem; line-height: 16px; - color: var(--red_7); + color: var(--color-negative-content); } .login_page_new_ui .field_errors li { margin-top: .25rem; @@ -214,10 +235,10 @@ html, body { .auto-generated form input { height: 40px; min-height: 40px; - background: var(--sand_0); + background: var(--color-neutral-surface); font-size: 1rem; line-height: 22px; - border: 1px solid var(--sand_300); + border: 1px solid var(--color-neutral-border); box-sizing: border-box; border-radius: 5px; padding: 0 16px; @@ -298,11 +319,11 @@ label{ content: ''; display: block; position: absolute; - top: 1px; + top: 2px; left: 8px; width: 5px; - height: 12px; - border: solid var(--sand_0); + height: 10px; + border: solid var(--color-primary-surface-content); border-width: 0 2px 2px 0; transform: rotate(45deg); } diff --git a/label_studio/core/static/css/main.css b/label_studio/core/static/css/main.css index 4457d0a6a40f..132ee7d4273f 100644 --- a/label_studio/core/static/css/main.css +++ b/label_studio/core/static/css/main.css @@ -2,10 +2,11 @@ html { overflow-x: auto; } -body { +:root { --font-sans: 'Figtree', sans-serif !important; --font-mono: Monaco, monospace; + /* Deprecated: [DO NOT USE] */ --sand_900: #12110D; --sand_800: #262522; --sand_700: #45433E; @@ -50,11 +51,276 @@ body { --primary_link: #566FCF; overflow-x: unset !important; + + /* Primitive Tokens [DO NOT USE] */ + /* Primitive Tokens: Colors */ + --color-blueberry-000: rgb(240 247 254); + --color-blueberry-100: rgb(212 231 251); + --color-blueberry-200: rgb(182 214 248); + --color-blueberry-300: rgb(153 197 245); + --color-blueberry-400: rgb(83 158 238); + --color-blueberry-500: rgb(50 135 226); + --color-blueberry-600: rgb(43 120 202); + --color-blueberry-700: rgb(43 105 171); + --color-blueberry-800: rgb(37 80 126); + --color-blueberry-900: rgb(28 60 95); + --color-blueberry-950: rgb(11 24 38); + --color-canteloupe-000: rgb(255 246 239); + --color-canteloupe-100: rgb(255 228 208); + --color-canteloupe-200: rgb(255 211 177); + --color-canteloupe-300: rgb(255 184 130); + --color-canteloupe-400: rgb(255 166 99); + --color-canteloupe-500: rgb(230 149 89); + --color-canteloupe-600: rgb(204 133 79); + --color-canteloupe-700: rgb(179 116 69); + --color-canteloupe-800: rgb(153 100 58); + --color-canteloupe-900: rgb(102 66 40); + --color-canteloupe-950: rgb(51 28 20); + --color-fig-000: rgb(248 242 252); + --color-fig-100: rgb(233 214 247); + --color-fig-200: rgb(218 189 241); + --color-fig-300: rgb(197 149 233); + --color-fig-400: rgb(172 121 210); + --color-fig-500: rgb(159 108 198); + --color-fig-600: rgb(146 98 182); + --color-fig-700: rgb(127 86 159); + --color-fig-800: rgb(109 74 136); + --color-fig-900: rgb(91 62 114); + --color-fig-950: rgb(31 21 38); + --color-grape-000: rgb(240 243 254); + --color-grape-100: rgb(212 219 251); + --color-grape-200: rgb(182 195 248); + --color-grape-300: rgb(153 171 245); + --color-grape-400: rgb(109 135 241); + --color-grape-500: rgb(97 122 218); + --color-grape-600: rgb(87 108 193); + --color-grape-700: rgb(76 95 169); + --color-grape-800: rgb(55 68 122); + --color-grape-900: rgb(43 54 96); + --color-grape-950: rgb(17 22 38); + --color-kale-000: rgb(244 249 249); + --color-kale-100: rgb(212 241 235); + --color-kale-200: rgb(171 228 218); + --color-kale-300: rgb(122 206 193); + --color-kale-400: rgb(87 183 171); + --color-kale-500: rgb(52 152 141); + --color-kale-600: rgb(40 122 114); + --color-kale-700: rgb(34 98 93); + --color-kale-800: rgb(32 79 77); + --color-kale-900: rgb(31 66 64); + --color-kale-950: rgb(18 38 37); + --color-kiwi-000: rgb(246 249 244); + --color-kiwi-100: rgb(222 241 212); + --color-kiwi-200: rgb(191 228 171); + --color-kiwi-300: rgb(151 206 122); + --color-kiwi-400: rgb(120 183 87); + --color-kiwi-500: rgb(87 152 52); + --color-kiwi-600: rgb(69 122 40); + --color-kiwi-700: rgb(56 98 34); + --color-kiwi-800: rgb(48 79 32); + --color-kiwi-900: rgb(43 66 31); + --color-kiwi-950: rgb(25 38 18); + --color-mango-000: rgb(255 249 239); + --color-mango-100: rgb(255 238 208); + --color-mango-200: rgb(255 226 177); + --color-mango-300: rgb(255 209 130); + --color-mango-400: rgb(250 186 76); + --color-mango-500: rgb(244 170 42); + --color-mango-600: rgb(235 156 20); + --color-mango-700: rgb(204 142 36); + --color-mango-800: rgb(160 114 34); + --color-mango-900: rgb(98 71 24); + --color-mango-950: rgb(38 28 10); + --color-persimmon-000: rgb(255 241 238); + --color-persimmon-100: rgb(255 214 205); + --color-persimmon-200: rgb(255 186 170); + --color-persimmon-300: rgb(255 159 137); + --color-persimmon-400: rgb(255 117 87); + --color-persimmon-500: rgb(230 105 78); + --color-persimmon-600: rgb(204 94 70); + --color-persimmon-700: rgb(179 82 61); + --color-persimmon-800: rgb(153 70 52); + --color-persimmon-900: rgb(128 59 44); + --color-persimmon-950: rgb(38 18 13); + --color-plum-000: rgb(251 242 252); + --color-plum-100: rgb(247 214 242); + --color-plum-200: rgb(241 189 233); + --color-plum-300: rgb(233 149 220); + --color-plum-400: rgb(227 123 211); + --color-plum-500: rgb(204 111 190); + --color-plum-600: rgb(182 98 169); + --color-plum-700: rgb(159 86 148); + --color-plum-800: rgb(136 74 128); + --color-plum-900: rgb(114 62 106); + --color-plum-950: rgb(38 21 36); + --color-sand-000: rgb(253 253 252); + --color-sand-100: rgb(249 248 246); + --color-sand-200: rgb(240 239 235); + --color-sand-300: rgb(225 222 213); + --color-sand-400: rgb(202 197 184); + --color-sand-500: rgb(164 159 149); + --color-sand-600: rgb(107 104 96); + --color-sand-700: rgb(69 67 62); + --color-sand-800: rgb(38 37 34); + --color-sand-850: rgb(30 29 26); + --color-sand-900: rgb(18 17 13); + --color-sand-950: rgb(13 12 9); + + /* Semantic Tokens */ + /* Semantic Tokens: Colors */ + + /* Light Color Scheme (Default) */ + --color-accent-blueberry-bold: var(--color-blueberry-600); + --color-accent-blueberry-dark: var(--color-blueberry-900); + --color-accent-blueberry-subtle: var(--color-blueberry-100); + --color-accent-blueberry-subtlest: var(--color-blueberry-000); + --color-accent-canteloupe-bold: var(--color-canteloupe-600); + --color-accent-canteloupe-dark: var(--color-canteloupe-900); + --color-accent-canteloupe-subtle: var(--color-canteloupe-100); + --color-accent-canteloupe-subtlest: var(--color-canteloupe-000); + --color-accent-fig-bold: var(--color-fig-600); + --color-accent-fig-dark: var(--color-fig-900); + --color-accent-fig-subtle: var(--color-fig-100); + --color-accent-fig-subtlest: var(--color-fig-000); + --color-accent-grape-bold: var(--color-grape-600); + --color-accent-grape-dark: var(--color-grape-900); + --color-accent-grape-subtle: var(--color-grape-100); + --color-accent-grape-subtlest: var(--color-grape-000); + --color-accent-kale-bold: var(--color-kale-600); + --color-accent-kale-dark: var(--color-kale-900); + --color-accent-kale-subtle: var(--color-kale-100); + --color-accent-kale-subtlest: var(--color-kale-000); + --color-accent-kiwi-bold: var(--color-kiwi-600); + --color-accent-kiwi-dark: var(--color-kiwi-900); + --color-accent-kiwi-subtle: var(--color-kiwi-100); + --color-accent-kiwi-subtlest: var(--color-kiwi-000); + --color-accent-mango-bold: var(--color-mango-600); + --color-accent-mango-dark: var(--color-mango-900); + --color-accent-mango-subtle: var(--color-mango-100); + --color-accent-mango-subtlest: var(--color-mango-000); + --color-accent-persimmon-bold: var(--color-persimmon-600); + --color-accent-persimmon-dark: var(--color-persimmon-900); + --color-accent-persimmon-subtle: var(--color-persimmon-100); + --color-accent-persimmon-subtlest: var(--color-persimmon-000); + --color-accent-plum-bold: var(--color-plum-600); + --color-accent-plum-dark: var(--color-plum-900); + --color-accent-plum-subtle: var(--color-plum-100); + --color-accent-plum-subtlest: var(--color-plum-000); + --color-accent-sand-bold: var(--color-sand-600); + --color-accent-sand-dark: var(--color-sand-900); + --color-accent-sand-subtle: var(--color-sand-100); + --color-accent-sand-subtlest: var(--color-sand-100); + --color-negative-background: var(--color-persimmon-000); + --color-negative-emphasis: var(--color-persimmon-100); + --color-negative-emphasis-subtle: var(--color-persimmon-000); + --color-negative-border: var(--color-persimmon-700); + --color-negative-border-bold: var(--color-persimmon-800); + --color-negative-border-subtle: var(--color-persimmon-500); + --color-negative-border-subtler: var(--color-persimmon-300); + --color-negative-border-subtlest: var(--color-persimmon-200); + --color-negative-content: var(--color-persimmon-700); + --color-negative-content-hover: var(--color-persimmon-500); + --color-negative-content-subtle: var(--color-persimmon-500); + --color-negative-focus-outline: var(--color-persimmon-200); + --color-negative-icon: var(--color-persimmon-500); + --color-negative-surface: var(--color-persimmon-600); + --color-negative-surface-content: var(--color-persimmon-000); + --color-negative-surface-content-subtle: var(--color-persimmon-100); + --color-negative-surface-active: var(--color-persimmon-800); + --color-negative-surface-icon: var(--color-persimmon-100); + --color-negative-surface-hover: var(--color-persimmon-500); + --color-neutral-background: var(--color-sand-000); + --color-neutral-background-bold: var(--color-sand-000); + --color-neutral-emphasis: var(--color-sand-200); + --color-neutral-emphasis-subtle: var(--color-sand-100); + --color-neutral-border: var(--color-sand-300); + --color-neutral-border-bold: var(--color-sand-400); + --color-neutral-border-bolder: var(--color-sand-500); + --color-neutral-border-boldest: var(--color-sand-600); + --color-neutral-border-subtle: var(--color-sand-300); + --color-neutral-border-subtler: var(--color-sand-200); + --color-neutral-content: var(--color-sand-800); + --color-neutral-content-subtle: var(--color-sand-700); + --color-neutral-content-subtler: var(--color-sand-600); + --color-neutral-content-subtlest: var(--color-sand-500); + --color-neutral-icon: var(--color-sand-700); + --color-neutral-shadow: var(--color-sand-900); + --color-neutral-surface: var(--color-sand-100); + --color-neutral-surface-active: var(--color-sand-200); + --color-neutral-surface-hover: var(--color-sand-000); + --color-neutral-surface-inset: var(--color-sand-200); + --color-neutral-inverted-background: var(--color-sand-900); + --color-neutral-inverted-border: var(--color-sand-800); + --color-neutral-inverted-content: var(--color-sand-100); + --color-neutral-inverted-content-subtle: var(--color-sand-400); + --color-neutral-inverted-content-subtler: var(--color-sand-300); + --color-neutral-inverted-content-subtlest: var(--color-sand-500); + --color-neutral-inverted-surface: var(--color-sand-900); + --color-neutral-inverted-surface-active: var(--color-sand-700); + --color-neutral-inverted-surface-hover: var(--color-sand-800); + --color-positive-background: var(--color-kale-000); + --color-positive-emphasis: var(--color-kale-100); + --color-positive-emphasis-subtle: var(--color-kale-000); + --color-positive-border: var(--color-kale-700); + --color-positive-border-bold: var(--color-kale-800); + --color-positive-border-subtle: var(--color-kale-500); + --color-positive-border-subtler: var(--color-kale-300); + --color-positive-border-subtlest: var(--color-kale-200); + --color-positive-content: var(--color-kale-700); + --color-positive-content-hover: var(--color-kale-500); + --color-positive-content-subtle: var(--color-kale-500); + --color-positive-focus-outline: var(--color-kale-200); + --color-positive-icon: var(--color-kale-500); + --color-positive-surface: var(--color-kale-600); + --color-positive-surface-content: var(--color-kale-000); + --color-positive-surface-content-subtle: var(--color-kale-100); + --color-positive-surface-active: var(--color-kale-800); + --color-positive-surface-icon: var(--color-kale-100); + --color-positive-surface-hover: var(--color-kale-500); + --color-primary-background: var(--color-grape-000); + --color-primary-emphasis: var(--color-grape-100); + --color-primary-emphasis-subtle: var(--color-grape-000); + --color-primary-border: var(--color-grape-700); + --color-primary-border-bold: var(--color-grape-800); + --color-primary-border-subtle: var(--color-grape-500); + --color-primary-border-subtler: var(--color-grape-300); + --color-primary-border-subtlest: var(--color-grape-200); + --color-primary-content: var(--color-grape-700); + --color-primary-content-hover: var(--color-grape-500); + --color-primary-content-subtle: var(--color-grape-500); + --color-primary-focus-outline: var(--color-grape-200); + --color-primary-icon: var(--color-grape-500); + --color-primary-shadow: var(--color-grape-900); + --color-primary-surface: var(--color-grape-700); + --color-primary-surface-content: var(--color-grape-000); + --color-primary-surface-content-subtle: var(--color-grape-100); + --color-primary-surface-active: var(--color-grape-800); + --color-primary-surface-icon: var(--color-grape-100); + --color-primary-surface-hover: var(--color-grape-600); + --color-warning-background: var(--color-canteloupe-000); + --color-warning-emphasis: var(--color-canteloupe-200); + --color-warning-emphasis-subtle: var(--color-canteloupe-100); + --color-warning-border: var(--color-canteloupe-700); + --color-warning-border-bold: var(--color-canteloupe-800); + --color-warning-border-subtle: var(--color-canteloupe-500); + --color-warning-border-subtler: var(--color-canteloupe-300); + --color-warning-border-subtlest: var(--color-canteloupe-200); + --color-warning-content: var(--color-canteloupe-700); + --color-warning-content-hover: var(--color-canteloupe-500); + --color-warning-content-subtle: var(--color-canteloupe-500); + --color-warning-focus-outline: var(--color-canteloupe-200); + --color-warning-icon: var(--color-canteloupe-500); + --color-warning-surface: var(--color-canteloupe-600); + --color-warning-surface-content: var(--color-canteloupe-000); + --color-warning-surface-content-subtle: var(--color-canteloupe-100); + --color-warning-surface-active: var(--color-canteloupe-800); + --color-warning-surface-icon: var(--color-canteloupe-100); + --color-warning-surface-hover: var(--color-canteloupe-500); } h1, h2, h3, h4, h5, h6 { font-weight: normal; - color: var(--sand_900); + color: var(--color-neutral-content); } a { text-decoration: none; @@ -154,7 +420,7 @@ pre { } main.main { - background: #FCFCFC !important; + background: var(--color-neutral-background); padding: 2em 4rem 2rem 2rem; } @@ -741,3 +1007,7 @@ hotkey i { .button.light-blue:hover { background: rgb(50, 149, 230) !important; } + +.ant-modal-content { + background-color: var(--color-neutral-background); +} \ No newline at end of file diff --git a/label_studio/core/static/css/uikit.css b/label_studio/core/static/css/uikit.css index 07677d28e752..4bbcb0a3cb0c 100644 --- a/label_studio/core/static/css/uikit.css +++ b/label_studio/core/static/css/uikit.css @@ -1,6 +1,6 @@ body { - --border-color: rgba(0, 0, 0, 0.15); - --color-error: #d00; + --border-color: varf(--color-neutral-border); + --color-error: var(--color-negative-content); } .full_content { @@ -63,8 +63,8 @@ textarea { } input[type=text][disabled] { - background: rgba(0, 0, 0, 0.03); - color: rgba(0, 0, 0, 0.4) + background: var(--color-neutral-background); + color: var(--color-neutral-content-subtlest); } a.button, @@ -110,7 +110,7 @@ input[type=submit][disabled], input[type=reset][disabled], button[disabled] { background: rgba(0, 0, 0, 0.2); - border-color: transparent; + border-color: 1px solid var(--color-neutral-border); cursor: not-allowed; } diff --git a/label_studio/core/static/css/users.css b/label_studio/core/static/css/users.css index 788e1672e8cf..fddb0a3820d1 100644 --- a/label_studio/core/static/css/users.css +++ b/label_studio/core/static/css/users.css @@ -1,22 +1,54 @@ /* Account page */ body { - --border-color: var(--sand_300); - --color-error: #d00; + --border-color: var(--color-neutral-border); + --color-error: var(--color-negative-content-bold); + color: var(--color-neutral-content); } .account-page { - display: grid; - grid-template: auto / 1fr 1fr; + display: flex; + flex-flow: row wrap; gap: 24px; + max-width: 990px; +} + +.account-page .forms { + display: flex; + flex-flow: column nowrap; + gap: 40px; + flex-grow: 4; + min-width: 500px; } -.account-page > * { + +.account-page .forms > * { + display: flex; + flex-direction: column; border: 1px solid var(--border-color); padding: 24px; display: flex; border-radius: 8px; + gap: 24px; +} + +.account-page .organization-panel { + display: flex; flex-direction: column; - gap: 40px; + background: var(--color-neutral-surface); + gap: 48px; + min-width: 340px; + border: 1px solid var(--border-color); + padding: 24px; + display: flex; + border-radius: 8px; + flex-grow: 1.5; } + +.account-page .organization { + display: flex; + flex-flow: column; + gap: 24px; +} + .account-page header { font-size: 1.5em; font-weight: 500; @@ -24,7 +56,7 @@ body { .account-page header sub{ font-size: .875rem; - color: var(--sand_600); + color: var(--color-neutral-content-subtler); } .account-page form ul { margin: 0; @@ -39,21 +71,53 @@ body { gap: 16px; justify-content: space-between; } + +.account-page textarea { + border: 1px solid var(--color-neutral-border); + border-radius: var(--radius-xs); + background: var(--color-neutral-surface); + color: var(--color-neutral-content); +} + +.account-page input[type=file]::before { + text-shadow: none; + border-radius: var(--radius-xs); + transition: all 150ms ease-out; +} + +.account-page input[type=file]:hover::before { + border: 1px solid var(--color-neutral-border-bold); +} + +.account-page .organization table { + width: 100%; +} + +.account-page .organization td:nth-child(2) { + text-align: right; +} + .user-pic { - display: grid; - grid-template: auto / 92px auto; - align-items: start; - column-gap: 16px; + display: flex; + flex-flow: row nowrap; + gap: 24px; + align-items: center; } + +.user-pic .userpic { + background-color: var(--color-neutral-surface); + box-shadow: inset 0 0 0 1px var(--color-neutral-border); + transition: all 150ms ease-out; + color: var(--color-neutral-content-subtler); +} + .userpic > span { text-transform: uppercase; } .user-pic > *:first-child { grid-row: span 2; } -.user-pic > *:last-child { - align-self: end; -} + .user-pic input, .user-pic button { display: none; @@ -72,7 +136,7 @@ body { } .user-activity p { margin-bottom: 10px; - color: rgba(0, 0, 0, 0.6); + color: var(--color-neutral-content-subtler); } .account-page footer { display: flex; @@ -80,7 +144,7 @@ body { align-items: center; } .account-page footer p { - color: var(--sand_600); + color: var(--color-neutral-content-subtler); margin: 0; } @@ -93,7 +157,7 @@ body { } #users table { font-size: 20px; - border: 1px solid rgba(0, 0, 0, 0.15); + border: 1px solid var(--border-color); text-align: left; } #users table thead { @@ -136,7 +200,7 @@ body { grid-template: auto / 64px auto; column-gap: 16px; line-height: 1.5; - color: rgba(0, 0, 0, 0.6); + color: var(--color-neutral-content); } .user-info__header > .email { margin-top: 0 !important; @@ -293,4 +357,4 @@ button.blinking-status.blink::after { .block-info table td { font-size: 100%; padding: 5px 0; -} \ No newline at end of file +} diff --git a/label_studio/core/static/icons/logo-black.svg b/label_studio/core/static/icons/logo-black.svg index 4f603b2473a4..4ffd061b0fb8 100644 --- a/label_studio/core/static/icons/logo-black.svg +++ b/label_studio/core/static/icons/logo-black.svg @@ -1,22 +1,22 @@ - - + + + + + + + + + + + + + - - - - - - - - - - - - - + + - + \ No newline at end of file diff --git a/label_studio/core/static/icons/logo.svg b/label_studio/core/static/icons/logo.svg index 4f603b2473a4..91ee34cdf280 100644 --- a/label_studio/core/static/icons/logo.svg +++ b/label_studio/core/static/icons/logo.svg @@ -3,17 +3,17 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/label_studio/core/templates/home/home.html b/label_studio/core/templates/home/home.html new file mode 100644 index 000000000000..3d19a4ecfce8 --- /dev/null +++ b/label_studio/core/templates/home/home.html @@ -0,0 +1,3 @@ +{% extends 'base.html' %} +{% load i18n %} +{% load static %} diff --git a/label_studio/core/views.py b/label_studio/core/views.py index 7c048a19e8ea..94e0447ec93f 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, 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 @@ -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 @@ -55,7 +55,11 @@ def main(request): 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') + else: + return redirect(reverse('projects:project-index')) # not authenticated return redirect(reverse('user-login')) diff --git a/label_studio/templates/base.html b/label_studio/templates/base.html index 4332b90ce238..b5419fbfe812 100644 --- a/label_studio/templates/base.html +++ b/label_studio/templates/base.html @@ -27,6 +27,21 @@ {% endblock %} + {% block theme_colors %} + + {% endblock %} + {% block app-scripts %} {% endblock %} @@ -52,6 +67,7 @@ {% get_current_language as LANGUAGE_CODE %} {% get_available_languages as LANGUAGES %} + diff --git a/label_studio/templates/simple.html b/label_studio/templates/simple.html index b21fd945f840..adc27aff5ad4 100644 --- a/label_studio/templates/simple.html +++ b/label_studio/templates/simple.html @@ -26,6 +26,21 @@ {% block head %} {% endblock %} + + {% block theme_colors %} + + {% endblock %} diff --git a/label_studio/users/templates/users/new-ui/user_base.html b/label_studio/users/templates/users/new-ui/user_base.html index 0407e9910d2d..e8be810dfed6 100644 --- a/label_studio/users/templates/users/new-ui/user_base.html +++ b/label_studio/users/templates/users/new-ui/user_base.html @@ -75,14 +75,54 @@