Files
site-portfolio/public/en/cases/orc-automation-panel/index.html
T
root daa623fe73 feat(mesh-bg): fade-in шейдера фона + modulepreload графа
- canvas стартует с opacity:0 и плавно проявляется (0.9s) при .is-ready
- initPageMeshShader ставит is-ready после первого кадра
- modulepreload page-mesh-shader.js для параллельной загрузки с main.js
- пересборка страниц (build:pages)
2026-09-24 21:37:40 +02:00

1024 lines
57 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en" data-theme="dark" data-radius="medium" data-font="merriweather">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta
name="description"
content="Case Study: Redesign of the Primo RPA Orchestrator Web Dashboard — design oversight, implementation of Ant Design and Storybook, and token synchronization with Figma."
/>
<title>Web Dashboard for Automation Orchestration — Case Study</title>
<script>
(function () {
var FONT_CSS = {
merriweather: "/assets/fonts/merriweather.css",
geologica: "/assets/fonts/geologica.css",
mono: "/assets/fonts/mono.css",
};
try {
var t = JSON.parse(localStorage.getItem("siteThemeV1") || "{}");
var d = document.documentElement;
var m = t.mode;
if (m !== "light" && m !== "dark" && m !== "system") m = "system";
var eff =
m === "system"
? window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light"
: m;
d.dataset.theme = eff;
var h = typeof t.h === "number" ? t.h : typeof t.hue === "number" ? t.hue : null;
var s = typeof t.s === "number" ? t.s : typeof t.sat === "number" ? t.sat : null;
var l = typeof t.l === "number" ? t.l : typeof t.light === "number" ? t.light : null;
if (h !== null) d.style.setProperty("--theme-h", String(h));
if (s !== null) d.style.setProperty("--theme-s", String(s));
if (l !== null) {
var L = Number(l);
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
}
var hVal = h !== null ? h : 210;
var sVal = s !== null ? s : 90;
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
var H = (((hVal % 360) + 360) % 360) / 360;
var S = Math.min(100, Math.max(0, sVal)) / 100;
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
var r, g, b;
if (S === 0) { r = g = b = Lv; }
else {
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
var p = 2 * Lv - q;
var hue2rgb = function(p, q, t) {
if (t < 0) t += 1; if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
};
r = hue2rgb(p, q, H + 1/3);
g = hue2rgb(p, q, H);
b = hue2rgb(p, q, H - 1/3);
}
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
var rad = t.radius;
if (rad === "soft" || rad === "medium" || rad === "strong") {
d.dataset.radius = rad;
} else {
d.dataset.radius = "medium";
}
var f = t.font;
if (f === "onest") f = "geologica";
if (f === "anonymous") f = "mono";
if (f !== "merriweather" && f !== "mono" && f !== "geologica") f = "merriweather";
d.dataset.font = f;
var mb = t.meshBg;
if (mb === "off") {
d.dataset.meshBg = "off";
} else {
d.dataset.meshBg = "on";
}
var href = FONT_CSS[f];
if (href && !document.querySelector('link[data-theme-font="' + f + '"]')) {
var link = document.createElement("link");
link.rel = "stylesheet";
link.href = href;
link.setAttribute("data-theme-font", f);
document.head.appendChild(link);
}
} catch (e) {}
})();
</script>
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon/favicon-16x16.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/assets/favicon/apple-touch-icon.png" />
<link rel="manifest" href="/assets/favicon/site.webmanifest" />
<link rel="preload" href="/assets/fonts/merriweather.css" as="style" />
<link rel="preload" href="/css/main.css" as="style" />
<link rel="preload" href="/js/skill-connectors.js" as="script" />
<link rel="modulepreload" href="/js/main.js" />
<link rel="modulepreload" href="/js/modules/ui/page-mesh-shader.js" />
<link rel="stylesheet" href="/css/main.css" />
<link rel="canonical" href="https://mamadaevv.site/en/cases/orc-automation-panel/" />
<link rel="alternate" hreflang="ru" href="https://mamadaevv.site/cases/orc-automation-panel/" />
<link rel="alternate" hreflang="en" href="https://mamadaevv.site/en/cases/orc-automation-panel/" />
<link rel="alternate" hreflang="x-default" href="https://mamadaevv.site/cases/orc-automation-panel/" />
<meta name="author" content="Nikolai Mamadaev" />
<meta name="robots" content="index, follow" />
<meta name="theme-color" content="#0f1115" />
<!-- Open Graph -->
<meta property="og:type" content="article" />
<meta property="og:site_name" content="Nikolai Mamadaev — Product Designer" />
<meta property="og:locale" content="en_US" />
<meta property="og:locale:alternate" content="ru_RU" />
<meta property="og:title" content="Web Dashboard for Automation Orchestration — Case Study" />
<meta property="og:description" content="Case Study: Redesign of the Primo RPA Orchestrator Web Dashboard — design oversight, implementation of Ant Design and Storybook, and token synchronization with Figma." />
<meta property="og:url" content="https://mamadaevv.site/en/cases/orc-automation-panel/" />
<meta property="og:image" content="https://mamadaevv.site/assets/og/og-default.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Web Dashboard for Automation Orchestration — Case Study" />
<!-- Twitter / X -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Web Dashboard for Automation Orchestration — Case Study" />
<meta name="twitter:description" content="Case Study: Redesign of the Primo RPA Orchestrator Web Dashboard — design oversight, implementation of Ant Design and Storybook, and token synchronization with Figma." />
<meta name="twitter:image" content="https://mamadaevv.site/assets/og/og-default.png" />
<meta name="twitter:image:alt" content="Web Dashboard for Automation Orchestration — Case Study" />
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Person",
"@id": "https://mamadaevv.site/#person",
"name": "Nikolai Mamadaev",
"url": "https://mamadaevv.site",
"jobTitle": "Product Designer",
"description": "Product designer with 10+ years of experience. Designing digital products, interfaces and design systems.",
"knowsAbout": [
"UX/UI design",
"product design",
"design systems",
"prototyping",
"Figma",
"no-code"
],
"sameAs": [
"https://t.me/mamadaevv",
"https://vk.com/mamadaevv",
"https://github.com/mamadaevv"
]
},
{
"@type": "WebSite",
"@id": "https://mamadaevv.site/#website",
"url": "https://mamadaevv.site/",
"name": "Nikolai Mamadaev — Product Designer",
"inLanguage": "en",
"author": {
"@id": "https://mamadaevv.site/#person"
},
"publisher": {
"@id": "https://mamadaevv.site/#person"
}
},
{
"@type": "CreativeWork",
"@id": "https://mamadaevv.site/en/cases/orc-automation-panel/#page",
"url": "https://mamadaevv.site/en/cases/orc-automation-panel/",
"name": "Web Dashboard for Automation Orchestration — Case Study",
"description": "Case Study: Redesign of the Primo RPA Orchestrator Web Dashboard — design oversight, implementation of Ant Design and Storybook, and token synchronization with Figma.",
"isPartOf": {
"@id": "https://mamadaevv.site/#website"
},
"author": {
"@id": "https://mamadaevv.site/#person"
},
"inLanguage": "en",
"creator": {
"@id": "https://mamadaevv.site/#person"
},
"datePublished": "2026-09-24",
"about": "UX/UI design and interface design"
},
{
"@type": "BreadcrumbList",
"@id": "https://mamadaevv.site/en/cases/orc-automation-panel/#breadcrumbs",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Nikolai Mamadaev — Product Designer",
"item": "https://mamadaevv.site/"
},
{
"@type": "ListItem",
"position": 2,
"name": "Cases",
"item": "https://mamadaevv.site/cases/"
},
{
"@type": "ListItem",
"position": 3,
"name": "Web Dashboard for Automation Orchestration — Case Study",
"item": "https://mamadaevv.site/cases/orc-automation-panel/"
}
]
}
]
}
</script>
<script src="/js/skill-connectors.js" defer></script>
<script type="module" src="/js/main.js"></script>
<style>
.case-article {
max-width: 48rem;
margin: 0 auto;
}
.case-article h2 {
margin: 2rem 0 0.75rem;
font-size: clamp(1.15rem, 2vw, 1.35rem);
font-weight: 700;
color: var(--text);
}
.case-article h3 {
font-size: 1.05rem;
font-weight: 600;
color: var(--text);
margin: 1.25rem 0 0.5rem;
}
.case-article .section__prose {
margin-bottom: 0.75rem;
color: var(--text);
}
.case-article img {
display: block;
max-width: 100%;
height: auto;
margin: 0.75rem 0 1rem;
}
.case-article ul {
margin: 0.5rem 0 1rem 1.25rem;
padding: 0;
}
.case-article li {
margin-bottom: 0.35rem;
}
.case-article a:not(.btn) {
color: var(--accent);
}
</style>
<script>
(function () {
try {
var t = JSON.parse(localStorage.getItem("siteThemeV1") || "{}");
var d = document.documentElement;
var m = t.mode;
if (m !== "light" && m !== "dark" && m !== "system") m = "system";
var eff =
m === "system"
? window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light"
: m;
d.dataset.theme = eff;
var h = typeof t.h === "number" ? t.h : typeof t.hue === "number" ? t.hue : null;
var s = typeof t.s === "number" ? t.s : typeof t.sat === "number" ? t.sat : null;
var l = typeof t.l === "number" ? t.l : typeof t.light === "number" ? t.light : null;
if (h !== null) d.style.setProperty("--theme-h", String(h));
if (s !== null) d.style.setProperty("--theme-s", String(s));
if (l !== null) {
var L = Number(l);
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
}
var rad = t.radius;
if (rad === "soft" || rad === "medium" || rad === "strong") {
d.dataset.radius = rad;
} else {
d.dataset.radius = "medium";
}
var f = t.font;
if (f === "onest") f = "geologica";
if (f === "anonymous") f = "mono";
if (f === "merriweather" || f === "mono" || f === "geologica") {
d.dataset.font = f;
} else {
d.dataset.font = "merriweather";
}
var mb = t.meshBg;
if (mb === "off") {
d.dataset.meshBg = "off";
} else {
d.dataset.meshBg = "on";
}
} catch (e) {}
})();
</script>
</head>
<body data-current-case="orc-automation-panel">
<svg class="liquid-glass-defs" aria-hidden="true" width="0" height="0" focusable="false" style="position:absolute;width:0;height:0;overflow:hidden;pointer-events:none">
<filter id="liquid-glass-displacement" x="-20%" y="-20%" width="140%" height="140%" color-interpolation-filters="sRGB">
<feImage href="../../../assets/liquid-glass/displacement.png" xlink:href="../../../assets/liquid-glass/displacement.png" preserveAspectRatio="none" result="lgMap"/>
<feDisplacementMap in="SourceGraphic" in2="lgMap" scale="14" xChannelSelector="R" yChannelSelector="G"/>
</filter>
<filter id="liquid-glass-displacement-btn" x="-20%" y="-20%" width="140%" height="140%" color-interpolation-filters="sRGB">
<feImage href="../../../assets/liquid-glass/displacement.png" xlink:href="../../../assets/liquid-glass/displacement.png" preserveAspectRatio="none" result="lgMapBtn"/>
<feDisplacementMap in="SourceGraphic" in2="lgMapBtn" scale="6" xChannelSelector="R" yChannelSelector="G"/>
</filter>
</svg>
<a class="skip-link" href="#case-main">Skip to case content</a>
<header class="header" data-theme-picker>
<div class="header__inner">
<a class="logo" href="../../" aria-label="Home">NM</a>
<div class="header__cluster">
<nav class="nav" aria-label="Page sections">
<a href="#contact">Contact</a>
</nav>
</div>
</div>
</header>
<div class="fab-stack" aria-label="Quick actions">
<div class="theme-panel-fab-wrap">
<button type="button" class="fab fab--secondary glass-neutral" data-theme-panel-btn aria-expanded="false" aria-controls="theme-panel" aria-label="Style settings">
<span class="theme-panel-fab__icon theme-panel-fab__icon--open-hide" aria-hidden="true"></span>
<svg class="theme-panel-fab__icon theme-panel-fab__icon--close" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path d="M6 6L18 18M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
</svg>
</button>
<div id="theme-panel" class="theme-picker__panel glass-neutral" role="dialog" aria-label="Theme &amp; appearance" hidden data-theme-panel>
<div class="theme-picker__stack">
<section class="theme-picker__section" aria-labelledby="theme-accent-title">
<h3 id="theme-accent-title" class="theme-picker__section-title">Accent color</h3>
<div class="colorpicker" data-colorpicker>
<div class="colorpicker__plane-box">
<canvas class="colorpicker__plane" width="320" height="180" data-sl-canvas aria-label="Accent saturation and lightness"></canvas>
<div class="colorpicker__knob" data-sl-knob></div>
</div>
<div class="colorpicker__hue-wrap">
<label class="colorpicker__hue-sr" for="theme-hue-slider">Accent hue</label>
<input id="theme-hue-slider" class="colorpicker__hue" type="range" min="0" max="360" value="210" data-hue-slider aria-valuemin="0" aria-valuemax="360" />
</div>
</div>
</section>
<section class="theme-picker__section" aria-labelledby="theme-mode-title">
<h3 id="theme-mode-title" class="theme-picker__section-title">Theme</h3>
<div class="radius-seg theme-mode-seg" role="radiogroup" aria-labelledby="theme-mode-title">
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="system" aria-label="System"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--system"></span></span></button>
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="light" aria-label="Light"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--light"></span></span></button>
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="dark" aria-label="Dark"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--dark"></span></span></button>
</div>
</section>
<section class="theme-picker__section" aria-labelledby="theme-radius-title">
<h3 id="theme-radius-title" class="theme-picker__section-title">Corner radius</h3>
<div class="radius-seg" role="radiogroup" aria-labelledby="theme-radius-title">
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="soft" aria-label="Soft radius"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--soft"></span></span></button>
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="medium" aria-label="Medium radius"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--medium"></span></span></button>
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="strong" aria-label="Strong radius"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--strong"></span></span></button>
</div>
</section>
<section class="theme-picker__section" aria-labelledby="theme-typography-title">
<h3 id="theme-typography-title" class="theme-picker__section-title">Typography</h3>
<div class="radius-seg" role="radiogroup" aria-labelledby="theme-typography-title">
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="geologica" aria-label="Sans"><span class="theme-font-seg__label">Sans</span></button>
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="merriweather" aria-label="Sans Serif"><span class="theme-font-seg__label">Sans Serif</span></button>
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="mono" aria-label="Mono"><span class="theme-font-seg__label">Mono</span></button>
</div>
</section>
<section class="theme-picker__section" aria-labelledby="theme-mesh-bg-title">
<h3 id="theme-mesh-bg-title" class="theme-picker__section-title">Page background</h3>
<div class="radius-seg radius-seg--two" role="radiogroup" aria-labelledby="theme-mesh-bg-title">
<button type="button" class="radius-seg__btn theme-mesh-bg-seg__btn" role="radio" aria-checked="false" data-mesh-bg-option="on" aria-label="Show background gradient"><span class="theme-mesh-bg-seg__label">On</span></button>
<button type="button" class="radius-seg__btn theme-mesh-bg-seg__btn" role="radio" aria-checked="false" data-mesh-bg-option="off" aria-label="Hide background gradient"><span class="theme-mesh-bg-seg__label">Off</span></button>
</div>
</section>
</div>
</div>
</div>
<a class="fab fab--primary" href="#contact" aria-label="Contact">
<span class="fab-primary__ico" aria-hidden="true"></span>
</a>
</div>
<div class="content-edit-fab-stack" aria-label="Content Edits" data-content-edit-ui>
<button
type="button"
class="fab fab--secondary glass-neutral content-edit-fab"
data-content-edit-mode-toggle
hidden
aria-pressed="false"
aria-label="Content Editing Mode"
title="Edit Mode"
>
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M4 20h4l10.5-10.5a2.12 2.12 0 0 0 0-3L16.5 4.5a2.12 2.12 0 0 0-3 0L3 15v5z"
stroke="currentColor"
stroke-width="1.75"
stroke-linejoin="round"
/>
</svg>
<span class="content-edit-fab__badge" hidden aria-hidden="true">0</span>
</button>
</div>
<main id="case-main" class="section section--tight">
<div class="section__inner case-article">
<p class="hero__eyebrow">Primo RPA · UX/UI · Web App</p>
<h1 class="case-page__h1">Web Dashboard for Automation Orchestration</h1>
<p class="case-page__sub">
Primo RPA Orchestrator: launching robots, managing projects, and monitoring processes in a web dashboard for administrators and automation developers.
</p>
<div class="case-block" id="obzor">
<h2>Context</h2>
<p class="section__prose">
In the Primo RPA stack, the orchestrator manages the scheduling, queue, and statuses of RPA robots on the client’s infrastructure. It can be accessed not only from the development studio but also from a browser: users view projects, restart tasks, and troubleshoot failures.
</p>
<p class="section__prose">
By that point, the product was already in use, but the interface was noticeably outdated: users faced navigation issues, visual clutter in tables, and confusing workflows in some sections. The goal was to refresh the interface’s look, modernize it, and fix the accumulated UX issues.
</p>
</div>
<div class="case-block" id="rol">
<h2>Role and Approach</h2>
<p class="section__prose">
My role in this project was more of a curatorial one—I didn’t do the design myself, but rather structured the process so that the design and development teams could work in sync.
</p>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">💡</span>
<div class="case-callout__content">
<p>I studied the product “from scratch”: I analyzed the orchestrator interface, identified user pain points, and formulated objectives for the update.</p>
</div>
</aside>
<p class="section__prose">
At the same time, I was looking for a designer who could take on the main visual design work. Elizaveta was selected—out of more than 150 applications, she was the best fit for the upcoming workload.
</p>
<p class="section__prose">
Over the course of three months, I brought the new team member up to speed on the project details: I assigned tasks, provided feedback on the mockups she created, and shared context on user scenarios. Together with the development team, we planned the order in which to update the service’s design—we revised screens based on priority, incorporating changes into ongoing releases, without “stopping everything and redesigning from scratch.”
</p>
</div>
<div class="case-block" id="tekhnicheskiy-stek">
<h2>Technical Stack and Tools</h2>
<p class="section__prose">
The latest version of <a href="https://ant.design/" target="_blank" rel="noopener noreferrer">Ant Design</a> was chosen as the UI framework. It was already in use on the project, and its latest release introduced <a href="https://ant.design/theme-editor" target="_blank" rel="noopener noreferrer">the Theme Editor</a>—a feature that allowed us to customize the appearance of components using design tokens without manually overriding styles. This provided both designers and developers with a unified language for describing the user interface.
</p>
<p class="section__prose">
<a href="https://storybook.js.org/" target="_blank" rel="noopener noreferrer">Storybook</a> served as the single source of truth and the bridge between design and development. In Storybook, components weren’t just documented—they actually worked in an isolated environment. This allowed designers to see the elements in action and developers to integrate components into the dashboard more quickly.
</p>
</div>
<div class="case-block" id="dizayn-sistema">
<h2>Design System and Synchronization</h2>
<p class="section__prose">
To streamline our workflow, we synchronized tokens from Ant Design with those in Figma—colors, padding, typography, and corner radii were standardized to consistent values. Here’s how it worked: if tokens were updated in Figma, they could be exported as JSON and immediately imported into the code without any issues—instead of having a developer manually search for changes and update each token individually. This approach also allowed us to view the design more systematically.
</p>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">📌</span>
<div class="case-callout__content">
<p>The main goal of this close collaboration between design and development was to translate the original vision into the product as accurately as possible without losing sight of the details along the way.</p>
</div>
</aside>
<p class="section__prose">
Components in Figma were built from scratch—based on Ant Design references, but without using pre-made libraries. The decision to avoid pre-made solutions was a conscious one: we needed full customization to fit our workflow and the ability to use new Figma features that weren’t supported in libraries from the Figma community.
</p>
<p class="section__prose">
For Storybook, we selected and configured plugins that were relevant to our tasks—accessibility checks, viewing component states, and switching themes and locales. This turned Storybook into more than just a showcase for components; it became a full-fledged design review tool.
</p>
</div>
<div class="case-block" id="rabochaya-sreda">
<h2>Designer’s Work Environment</h2>
<p class="section__prose">
We set up the environment so that designers could see the live implementation of components on their own computers using a local Storybook instance and Git. This allowed for more precise control over how the intended design was translated into code and enabled us to quickly spot discrepancies early on.
</p>
<p class="section__prose">
We also discussed a step to accelerate Storybook support by allowing designers to write the JSX for implemented components themselves—this shortened the path from mockup to a documented component in Storybook.
</p>
<p class="section__prose">
We fine-tuned the workflow for adding icons to the library. The key feature was that icons could be displayed in Storybook with filtering and sorting capabilities. At the same time, designers could update icons without involving a developer—they simply pushed new files to the repository.
</p>
<p class="section__prose">
Being able to see the updated icon immediately in the browser allowed us to optimize it better and eliminate display glitches when using Boolean operations.
</p>
<p class="section__prose">
We also developed an approach and set of rules for Figma that not only guided the designer but also ensured the creation of consistent and functional icons.
</p>
</div>
<div class="case-block" id="ux-uluchsheniya">
<h2>UX Improvements</h2>
<p class="section__prose">
During the interface update, Elizaveta also proposed a number of user experience improvements. Some of them were successfully implemented—for example, clearer grouping of elements in complex forms and redesigned loading states. However, the priority was not to disrupt the existing UX that users had grown accustomed to, so many ideas were saved for the backlog for the next iteration.
</p>
</div>
<div class="case-block" id="proekty">
<h2>Project List</h2>
<p class="section__prose">
The project table is one of the most frequently viewed screens. In the old version, there were many columns, a dense grid, and small text: the project status and name were difficult to read, especially on a laptop.
</p>
<p class="section__prose">In the new version:</p>
<ul>
<li>the columns have been reduced to what’s necessary for daily work;</li>
<li>statuses and actions have been moved to predictable areas within each row;</li>
<li>indentation and typography have been aligned with the rest of the panel using Ant Design.</li>
</ul>
<h3>It used to be</h3>
<figure class="case-media case-media--wide">
<img
src="../../../assets/orc-primo-rpa/projects--table-old.webp"
alt="List of projects in the orchestrator — previous version of the table"
width="1919"
height="867"
loading="lazy"
decoding="async"
data-image-viewer
/>
</figure>
<h3>Now</h3>
<figure class="case-media case-media--wide">
<img
src="../../../assets/orc-primo-rpa/projects--table-new.webp"
alt="List of Projects in the Orchestrator — Updated Table"
width="1366"
height="768"
loading="lazy"
decoding="async"
data-image-viewer
/>
</figure>
</div>
<div class="case-block" id="itog">
<h2>Results and Reflection</h2>
<p class="section__prose">
The projects screen became easier to scan: less visual noise, and it’s faster to find the right project and its status. After rolling out the new design to several clients, we received positive feedback and many ideas for further improvements.
</p>
<p class="section__prose">
I stepped away from the project once Elizaveta felt confident in her role and was able to handle design tasks independently. I occasionally answered specific questions, but overall, the handoff went smoothly.
</p>
<p class="section__prose">
A little over a year later, the team’s processes have changed significantly. According to the team, tools powered by neural networks—such as Claude Design—are now actively involved in the creation and handoff of designs. What we used to build manually using tokens, Storybook, and environment synchronization is now, to some extent, automated.
</p>
<p class="section__prose">
I believe the work was completed fairly quickly and to a high standard—amid constant changes in the market and within the company, we managed not only to update the interface but also to establish a sustainable process that continued to function even without my involvement.
</p>
</div>
</div>
</main>
<section class="section section--surface" data-reveal>
<div class="section__inner">
<h2 class="section__title">See also</h2>
<ol class="mini-projects-grid" data-mini-projects-list>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="ai-platform-primo-rpa">
<a class="mp-card mp-card--link mp-card--stack" href="../ai-platform-primo-rpa/" aria-label="AI Platform — Open a Case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../../../assets/ai-platform-primo-rpa/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Primo AI Server</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">UX/UI</li>
<li class="mp-card__tag">Web App</li>
</ul>
<p class="mp-card__desc">An interface for training and using AI models in business processes: working with data, automation scenarios, and Smart OCR.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="lunacy">
<a class="mp-card mp-card--link mp-card--stack" href="../lunacy/" aria-label="Lunacy Image Editor — Open a Case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../../../assets/lunacy/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Lunacy</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">UX/UI</li>
<li class="mp-card__tag">Desktop App</li>
</ul>
<p class="mp-card__desc">Worked on the Lunacy interface as part of the Icons8 team: user flow, complex prototypes, and improvements to functionality and interface logic.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="manu-game-maker" hidden>
<a class="mp-card mp-card--link mp-card--stack" href="../manu-game-maker/" aria-label="MANU Game Engine — Open a Case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../../../assets/manu-game-maker/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">MANU Game Engine</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">Product Design</li>
<li class="mp-card__tag">Desktop App</li>
</ul>
<p class="mp-card__desc">Redesign and development of the game engine’s user interface: a new operational concept, an updated visual system, and the development of hundreds of complex user scenarios.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="mobile-clinic-app" hidden>
<a class="mp-card mp-card--link mp-card--stack" href="../mobile-clinic-app/" aria-label="Mobile app for a network of clinics — open a case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../../../assets/mobile-clinic-app/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Mobile app for a network of clinics</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">UX/UI</li>
<li class="mp-card__tag">Mobile App</li>
</ul>
<p class="mp-card__desc">Design of a mobile app for scheduling doctor appointments and managing medical services. Focus on a simple user journey, intuitive navigation, and quick access to necessary actions.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="orc-automation-panel">
<a class="mp-card mp-card--link mp-card--stack" href="../orc-automation-panel/" aria-label="Web Panel for Automation Orchestration — Open a Case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../../../assets/orc-primo-rpa/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Primo Orc</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">Mentoring and Coaching</li>
</ul>
<p class="mp-card__desc">Primo RPA orchestrator’s web dashboard: projects, deployment, and monitoring of RPA robots. Redesign of key screens for production without interrupting releases.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="task-distribution-concept" hidden>
<a class="mp-card mp-card--link mp-card--stack" href="../task-distribution-concept/" aria-label="The concept of a task-assignment service—open a case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../../../assets/task-distribution-concept/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Task Distribution Service Concept</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">UX/UI</li>
<li class="mp-card__tag">Analytics</li>
</ul>
<p class="mp-card__desc">Product concept for a service to create, assign, and track tasks, with an emphasis on process transparency and seamless teamwork.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="task-tracker" hidden>
<a class="mp-card mp-card--link mp-card--stack" href="../task-tracker/" aria-label="Task Tracker for the Back-Office System — Open a Case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../../../assets/task-tracker/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Task tracker for a back-office system</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">Product Design</li>
<li class="mp-card__tag">Web App</li>
</ul>
<p class="mp-card__desc">An interface for planning and assigning tasks in the operations department: shared pool, personal to-do list, overview by assignee; tabs, filters, board/list/table views, and drag-and-drop functionality.</p>
</div>
</a>
</li>
</ol>
</div>
</section>
<section hidden class="section section--surface" aria-hidden="true">
<div class="section__inner">
<div class="projects__heading">
<h2 class="section__title projects__title">Portfolio</h2>
<div class="projects__controls" aria-label="Portfolio card navigation">
<button type="button" class="projects__nav-btn" data-projects-prev aria-label="Scroll left" aria-controls="projects-viewport">
<span class="projects__nav-ico projects__nav-ico--left" aria-hidden="true"></span>
</button>
<button type="button" class="projects__nav-btn" data-projects-next aria-label="Scroll right" aria-controls="projects-viewport">
<span class="projects__nav-ico projects__nav-ico--right" aria-hidden="true"></span>
</button>
</div>
</div>
<div class="projects-carousel">
<div id="projects-viewport" class="projects-carousel__viewport" data-projects-viewport>
<div class="projects-carousel__track">
<div class="projects-carousel__spacer" aria-hidden="true"></div>
<article class="projects-carousel__item">
<a class="portfolio-card" href="../orc-automation-panel/">
<div class="portfolio-card__body">
<h3 class="portfolio-card__title">Web panel for automation orchestration</h3>
<p class="portfolio-card__summary">
Primo RPA orchestrator web console: projects, launch and control of RPA bots. Redesign of key screens for production without halting releases.
</p>
<ul class="portfolio-card__tags" aria-label="Key tags">
<li class="portfolio-card__tag">UX/UI</li>
<li class="portfolio-card__tag">Web App</li>
</ul>
</div>
<div class="portfolio-card__cover" aria-hidden="true">
<img
class="portfolio-card__image"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
data-defer-src="../../../assets/orc-primo-rpa/cover.webp"
alt=""
width="400"
height="225"
decoding="async"
/>
</div>
</a>
</article>
<article class="projects-carousel__item">
<a class="portfolio-card" href="../ai-platform-primo-rpa/">
<div class="portfolio-card__body">
<h3 class="portfolio-card__title">Platform for working with AI</h3>
<p class="portfolio-card__summary">
Interface for training and using AI models in business processes: data work, automation scenarios, and Smart OCR.
</p>
<ul class="portfolio-card__tags" aria-label="Key tags">
<li class="portfolio-card__tag">UX/UI</li>
<li class="portfolio-card__tag">Web App</li>
</ul>
</div>
<div class="portfolio-card__cover" aria-hidden="true">
<img
class="portfolio-card__image"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
data-defer-src="../../../assets/ai-platform-primo-rpa/cover.webp"
alt=""
width="400"
height="225"
decoding="async"
/>
</div>
</a>
</article>
<article class="projects-carousel__item">
<a class="portfolio-card" href="../task-tracker/">
<div class="portfolio-card__body">
<h3 class="portfolio-card__title">Task tracker for a back-office system</h3>
<p class="portfolio-card__summary">
Interface for planning and distributing tasks in the operations department: shared pool, personal ToDo, per-assignee overview; tabs, filters, board / list / table views, drag &amp; drop.
</p>
<ul class="portfolio-card__tags" aria-label="Key tags">
<li class="portfolio-card__tag">Product Design</li>
<li class="portfolio-card__tag">Web App</li>
</ul>
</div>
<div class="portfolio-card__cover" aria-hidden="true">
<img
class="portfolio-card__image"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
data-defer-src="../../../assets/task-tracker/cover.webp"
alt=""
width="400"
height="225"
decoding="async"
/>
</div>
</a>
</article>
<article class="projects-carousel__item">
<a class="portfolio-card" href="../manu-game-maker/">
<div class="portfolio-card__body">
<h3 class="portfolio-card__title">MANU game engine</h3>
<p class="portfolio-card__summary">
Redesign and evolution of the game engine interface: a new working concept, refreshed visual system, and hundreds of complex user scenarios worked through.
</p>
<ul class="portfolio-card__tags" aria-label="Key tags">
<li class="portfolio-card__tag">Product Design</li>
<li class="portfolio-card__tag">Desktop App</li>
</ul>
</div>
<div class="portfolio-card__cover" aria-hidden="true">
<img
class="portfolio-card__image"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
data-defer-src="../../../assets/manu-game-maker/cover.webp"
alt=""
width="400"
height="225"
decoding="async"
/>
</div>
</a>
</article>
<article class="projects-carousel__item">
<a class="portfolio-card" href="../lunacy/">
<div class="portfolio-card__body">
<h3 class="portfolio-card__title">Graphics editor Lunacy</h3>
<p class="portfolio-card__summary">
Work on the Lunacy interface at Icons8: user flows, complex prototypes, improved functionality and interface logic.
</p>
<ul class="portfolio-card__tags" aria-label="Key tags">
<li class="portfolio-card__tag">UX/UI</li>
<li class="portfolio-card__tag">Desktop App</li>
</ul>
</div>
<div class="portfolio-card__cover" aria-hidden="true">
<img
class="portfolio-card__image"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
data-defer-src="../../../assets/lunacy/cover.webp"
alt=""
width="400"
height="225"
decoding="async"
/>
</div>
</a>
</article>
<article class="projects-carousel__item">
<a class="portfolio-card" href="../mobile-clinic-app/">
<div class="portfolio-card__body">
<h3 class="portfolio-card__title">Mobile app for a clinic network</h3>
<p class="portfolio-card__summary">
Design of a mobile app for booking doctors and managing medical services. Focus on a simple user path, clear navigation, and quick access to the right actions.
</p>
<ul class="portfolio-card__tags" aria-label="Key tags">
<li class="portfolio-card__tag">UX/UI</li>
<li class="portfolio-card__tag">Mobile App</li>
</ul>
</div>
<div class="portfolio-card__cover" aria-hidden="true">
<img
class="portfolio-card__image"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
data-defer-src="../../../assets/mobile-clinic-app/cover.webp"
alt=""
width="400"
height="225"
decoding="async"
/>
</div>
</a>
</article>
<article class="projects-carousel__item">
<a class="portfolio-card" href="../task-distribution-concept/">
<div class="portfolio-card__body">
<h3 class="portfolio-card__title">Task distribution service concept</h3>
<p class="portfolio-card__summary">
A product concept for a service to set, distribute and track tasks, with emphasis on process transparency and comfortable teamwork.
</p>
<ul class="portfolio-card__tags" aria-label="Key tags">
<li class="portfolio-card__tag">UX/UI</li>
<li class="portfolio-card__tag">Analytics</li>
</ul>
</div>
<div class="portfolio-card__cover" aria-hidden="true">
<img
class="portfolio-card__image"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
data-defer-src="../../../assets/task-distribution-concept/cover.webp"
alt=""
width="400"
height="225"
decoding="async"
/>
</div>
</a>
</article>
<article class="projects-carousel__item">
<a class="portfolio-card" href="../obsidian-plugin-columns-view/">
<div class="portfolio-card__body">
<h3 class="portfolio-card__title">Columns view — plugin for Obsidian</h3>
<p class="portfolio-card__summary">
Interface for multi-column note work: convenient navigation, filtering and column-view settings right inside the Obsidian editor.
</p>
<ul class="portfolio-card__tags" aria-label="Key tags">
<li class="portfolio-card__tag">UX/UI</li>
<li class="portfolio-card__tag">Plugin</li>
</ul>
</div>
<div class="portfolio-card__cover" aria-hidden="true">
<img
class="portfolio-card__image"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
data-defer-src="../../../assets/obsidian-plugin-columns-view/filter use.webp"
alt=""
width="400"
height="225"
decoding="async"
/>
</div>
</a>
</article>
<div class="projects-carousel__spacer" aria-hidden="true"></div>
</div>
</div>
<button
type="button"
class="projects-carousel__edge-hit projects-carousel__edge-hit--left"
data-projects-edge-prev
aria-label="Scroll portfolio left"
></button>
<button
type="button"
class="projects-carousel__edge-hit projects-carousel__edge-hit--right"
data-projects-edge-next
aria-label="Scroll portfolio right"
></button>
</div>
</div>
</section>
<section id="contact" class="section section--surface section--footerish" data-reveal>
<div class="section__inner">
<h2 class="section__title">Contact</h2>
<ul class="contact-grid">
<li><a class="contact-card contact-card--link contact-card--brand-tg" href="https://t.me/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../../../assets/shared/icons/tg.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Telegram</span><span class="contact-card__hint">I'll reply today</span></span></a></li>
<li><a class="contact-card contact-card--link contact-card--brand-whatsapp" href="https://wa.me/qr/E2AWW5ZHE3ANJ1" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../../../assets/shared/icons/whatsapp.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">WhatsApp</span><span class="contact-card__hint">Stable connection</span></span></a></li>
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5zaXRl" data-hint-default="Copy address" aria-label="Copy email address to clipboard"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Email</span><span class="contact-card__hint" data-contact-copy-hint>Copy address</span></span></button></li>
</ul>
</div>
</section>
<footer class="footer">
<div class="footer__inner">
<span class="footer__chunk footer__chunk--date">© 2015–2026<span class="footer__sep" aria-hidden="true"> ·
</span></span>
<span class="footer__chunk footer__chunk--main">Website design and development — Nikolay Mamadaev</span> ·<span class="footer__chunk footer__chunk--meta footer__attr"><span class="footer__sep" aria-hidden="true"> </span><a href="../../cases/design-system/">Design System</a><span class="footer__sep" aria-hidden="true">·
</span><a href="../../cookie-policy/">Cookie policy</a></span> ·<span class="footer__chunk footer__chunk--lang"><span class="footer__sep" aria-hidden="true">
</span><nav class="lang-switch" aria-label="Choose language" data-lang-switch>
<a class="lang-switch__btn" data-lang="ru" href="/">Русский</a>
</nav>
<script>
(function () {
var p = location.pathname.replace(/^\/+/, "");
var isEn = p.indexOf("en/") === 0;
var base = isEn ? p.slice(3) : p;
var links = document.querySelectorAll("[data-lang-switch] [data-lang]");
for (var i = 0; i < links.length; i++) {
var l = links[i].getAttribute("data-lang");
links[i].setAttribute("href", (l === "en" ? "/en/" : "/") + base);
}
})();
</script>
</span></div>
</footer>
<aside class="cookie-notice glass-neutral" hidden data-cookie-notice>
<p class="cookie-notice__text">
This site uses cookies to ensure a smooth user experience. For more information, see the
<a href="../../cookie-policy/" data-cookie-policy-link>cookie policy</a>.
</p>
<button type="button" class="btn btn--secondary btn--flat cookie-notice__accept" data-cookie-accept>
<span>Accept</span>
<span class="cookie-notice__accept-icon" aria-hidden="true"><img src="../../../assets/shared/icons/сookie.svg" alt="" width="20" height="20" loading="eager" decoding="async" /></span>
</button>
</aside>
<div id="nav-more-menu-floating" class="nav-more__floating" hidden data-nav-more-menu-floating aria-hidden="true"></div>
<script>
document.addEventListener('DOMContentLoaded',function(){
var s=document.body.dataset.currentCase;
if(!s)return;
document.querySelectorAll('[data-related-slug="'+s+'"]').forEach(function(el){el.hidden=true;});
});
</script>
</body>
</html>