Sync service launch links
This commit is contained in:
parent
17e007f49d
commit
c6e1de6345
|
|
@ -231,7 +231,7 @@
|
||||||
"subtitle": "Агентная платформа",
|
"subtitle": "Агентная платформа",
|
||||||
"description": "Сборка, запуск и мониторинг агентных workflow.",
|
"description": "Сборка, запуск и мониторинг агентных workflow.",
|
||||||
"fullDescription": "NodeDC используется для настройки агентных процессов, визуальной оркестрации, интеграций и runtime-мониторинга.",
|
"fullDescription": "NodeDC используется для настройки агентных процессов, визуальной оркестрации, интеграций и runtime-мониторинга.",
|
||||||
"url": "https://dev.handhdc.ru",
|
"url": "https://dev.handhdc.ru/sso/launch",
|
||||||
"launchUrl": "https://dev.handhdc.ru/sso/launch",
|
"launchUrl": "https://dev.handhdc.ru/sso/launch",
|
||||||
"accentColor": "#B5FF5A",
|
"accentColor": "#B5FF5A",
|
||||||
"fallbackGradient": "linear-gradient(128deg, rgba(181, 255, 90, 0.84), rgba(37, 58, 36, 0.86) 42%, #0A0D10 82%)",
|
"fallbackGradient": "linear-gradient(128deg, rgba(181, 255, 90, 0.84), rgba(37, 58, 36, 0.86) 42%, #0A0D10 82%)",
|
||||||
|
|
@ -257,7 +257,7 @@
|
||||||
"subtitle": "Операционный слой",
|
"subtitle": "Операционный слой",
|
||||||
"description": "Задачи, контуры предприятия, процессы и AI-функции поверх задачника.",
|
"description": "Задачи, контуры предприятия, процессы и AI-функции поверх задачника.",
|
||||||
"fullDescription": "Task Manager основан на архитектуре Plane и расширен AI-функциями NODE.DC.",
|
"fullDescription": "Task Manager основан на архитектуре Plane и расширен AI-функциями NODE.DC.",
|
||||||
"url": "https://tasks.handhdc.ru",
|
"url": "https://tasks.handhdc.ru/sso/launch",
|
||||||
"launchUrl": "https://tasks.handhdc.ru/sso/launch",
|
"launchUrl": "https://tasks.handhdc.ru/sso/launch",
|
||||||
"accentColor": "#D7C8FF",
|
"accentColor": "#D7C8FF",
|
||||||
"fallbackGradient": "linear-gradient(132deg, rgba(215, 200, 255, 0.82), rgba(51, 41, 79, 0.9) 46%, #0B0D10 84%)",
|
"fallbackGradient": "linear-gradient(132deg, rgba(215, 200, 255, 0.82), rgba(51, 41, 79, 0.9) 46%, #0B0D10 84%)",
|
||||||
|
|
@ -279,7 +279,7 @@
|
||||||
"subtitle": "Бухгалтерский ассистент",
|
"subtitle": "Бухгалтерский ассистент",
|
||||||
"description": "Вопросы к 1С, точные выборки и доказательная навигация по данным.",
|
"description": "Вопросы к 1С, точные выборки и доказательная навигация по данным.",
|
||||||
"fullDescription": "Ассистент для бухгалтерских запросов, анализа операций, остатков и документов.",
|
"fullDescription": "Ассистент для бухгалтерских запросов, анализа операций, остатков и документов.",
|
||||||
"url": "https://1c.handhdc.ru",
|
"url": "https://1c.handhdc.ru/sso/launch",
|
||||||
"launchUrl": "https://1c.handhdc.ru/sso/launch",
|
"launchUrl": "https://1c.handhdc.ru/sso/launch",
|
||||||
"accentColor": "#8FD7FF",
|
"accentColor": "#8FD7FF",
|
||||||
"fallbackGradient": "linear-gradient(126deg, rgba(143, 215, 255, 0.8), rgba(32, 61, 80, 0.9) 44%, #080B0F 84%)",
|
"fallbackGradient": "linear-gradient(126deg, rgba(143, 215, 255, 0.8), rgba(32, 61, 80, 0.9) 44%, #080B0F 84%)",
|
||||||
|
|
@ -301,7 +301,7 @@
|
||||||
"subtitle": "Госзакупки и тендеры",
|
"subtitle": "Госзакупки и тендеры",
|
||||||
"description": "Поиск, анализ и подготовка тендерных решений.",
|
"description": "Поиск, анализ и подготовка тендерных решений.",
|
||||||
"fullDescription": "Сервис собирает тендерные данные, строит выжимку рисков и помогает подготовить пакет участия.",
|
"fullDescription": "Сервис собирает тендерные данные, строит выжимку рисков и помогает подготовить пакет участия.",
|
||||||
"url": "https://tender.handhdc.ru",
|
"url": "https://tender.handhdc.ru/sso/launch",
|
||||||
"launchUrl": "https://tender.handhdc.ru/sso/launch",
|
"launchUrl": "https://tender.handhdc.ru/sso/launch",
|
||||||
"accentColor": "#FFD166",
|
"accentColor": "#FFD166",
|
||||||
"fallbackGradient": "linear-gradient(135deg, rgba(255, 209, 102, 0.84), rgba(74, 53, 19, 0.92) 42%, #0B0D10 86%)",
|
"fallbackGradient": "linear-gradient(135deg, rgba(255, 209, 102, 0.84), rgba(74, 53, 19, 0.92) 42%, #0B0D10 86%)",
|
||||||
|
|
@ -327,7 +327,7 @@
|
||||||
"subtitle": "3D и пространственные данные",
|
"subtitle": "3D и пространственные данные",
|
||||||
"description": "Просмотр цифровых двойников, карт и объектных сцен.",
|
"description": "Просмотр цифровых двойников, карт и объектных сцен.",
|
||||||
"fullDescription": "Витрина геометрии, объектов, слоёв и статусов инфраструктуры.",
|
"fullDescription": "Витрина геометрии, объектов, слоёв и статусов инфраструктуры.",
|
||||||
"url": "https://twin.handhdc.ru",
|
"url": "https://launch.dcserve.ru/",
|
||||||
"launchUrl": "https://launch.dcserve.ru/",
|
"launchUrl": "https://launch.dcserve.ru/",
|
||||||
"accentColor": "#76E4F7",
|
"accentColor": "#76E4F7",
|
||||||
"fallbackGradient": "linear-gradient(140deg, rgba(118, 228, 247, 0.82), rgba(23, 69, 87, 0.92) 47%, #080B0F 86%)",
|
"fallbackGradient": "linear-gradient(140deg, rgba(118, 228, 247, 0.82), rgba(23, 69, 87, 0.92) 47%, #080B0F 86%)",
|
||||||
|
|
@ -349,7 +349,7 @@
|
||||||
"subtitle": "Будущие модули",
|
"subtitle": "Будущие модули",
|
||||||
"description": "Скрытый каталог модулей для root-admin preview.",
|
"description": "Скрытый каталог модулей для root-admin preview.",
|
||||||
"fullDescription": "Площадка для будущих цифровых модулей NODE.DC.",
|
"fullDescription": "Площадка для будущих цифровых модулей NODE.DC.",
|
||||||
"url": "https://dm.handhdc.ru",
|
"url": "https://dm.handhdc.ru/sso/launch",
|
||||||
"launchUrl": "https://dm.handhdc.ru/sso/launch",
|
"launchUrl": "https://dm.handhdc.ru/sso/launch",
|
||||||
"accentColor": "#FF9AC2",
|
"accentColor": "#FF9AC2",
|
||||||
"fallbackGradient": "linear-gradient(135deg, rgba(255, 154, 194, 0.78), rgba(76, 41, 64, 0.9) 44%, #090B0F 86%)",
|
"fallbackGradient": "linear-gradient(135deg, rgba(255, 154, 194, 0.78), rgba(76, 41, 64, 0.9) 44%, #090B0F 86%)",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import type { Client } from "../entities/client/types";
|
import type { Client } from "../entities/client/types";
|
||||||
import type { Invite } from "../entities/invite/types";
|
import type { Invite } from "../entities/invite/types";
|
||||||
|
import { syncServiceLaunchLink } from "../entities/service/links";
|
||||||
import type { LauncherServiceView, Service } from "../entities/service/types";
|
import type { LauncherServiceView, Service } from "../entities/service/types";
|
||||||
import type { SyncStatus } from "../entities/sync/types";
|
import type { SyncStatus } from "../entities/sync/types";
|
||||||
import type { ClientGroup, ClientMembership, LauncherUser } from "../entities/user/types";
|
import type { ClientGroup, ClientMembership, LauncherUser } from "../entities/user/types";
|
||||||
|
|
@ -18,7 +19,7 @@ import { ServiceStage } from "../widgets/service-stage/ServiceStage";
|
||||||
import { TopBar } from "../widgets/top-bar/TopBar";
|
import { TopBar } from "../widgets/top-bar/TopBar";
|
||||||
|
|
||||||
export function LauncherApp() {
|
export function LauncherApp() {
|
||||||
const [data, setData] = useState<LauncherData>(initialLauncherData);
|
const [data, setData] = useState<LauncherData>(() => syncLauncherServiceLinks(initialLauncherData));
|
||||||
const [activeProfileId, setActiveProfileId] = useState(profileOptions[0].userId);
|
const [activeProfileId, setActiveProfileId] = useState(profileOptions[0].userId);
|
||||||
const [activeClientId, setActiveClientId] = useState(profileOptions[0].defaultClientId);
|
const [activeClientId, setActiveClientId] = useState(profileOptions[0].defaultClientId);
|
||||||
const [selectedServiceId, setSelectedServiceId] = useState<string | undefined>();
|
const [selectedServiceId, setSelectedServiceId] = useState<string | undefined>();
|
||||||
|
|
@ -51,7 +52,7 @@ export function LauncherApp() {
|
||||||
loadPersistedLauncherData()
|
loadPersistedLauncherData()
|
||||||
.then((persistedData) => {
|
.then((persistedData) => {
|
||||||
if (isMounted && persistedData) {
|
if (isMounted && persistedData) {
|
||||||
setData(persistedData);
|
setData(syncLauncherServiceLinks(persistedData));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
|
@ -232,11 +233,11 @@ export function LauncherApp() {
|
||||||
...current,
|
...current,
|
||||||
services: current.services.map((service) =>
|
services: current.services.map((service) =>
|
||||||
service.id === serviceId
|
service.id === serviceId
|
||||||
? {
|
? syncServiceLaunchLink({
|
||||||
...service,
|
...service,
|
||||||
...patch,
|
...patch,
|
||||||
updatedAt: new Date().toISOString(),
|
updatedAt: new Date().toISOString(),
|
||||||
}
|
})
|
||||||
: service
|
: service
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
|
@ -444,7 +445,7 @@ export function LauncherApp() {
|
||||||
subtitle: "Новый сервис",
|
subtitle: "Новый сервис",
|
||||||
description: "Описание сервиса для витрины.",
|
description: "Описание сервиса для витрины.",
|
||||||
fullDescription: "Заполните описание, медиа и ссылку запуска в редакторе контента.",
|
fullDescription: "Заполните описание, медиа и ссылку запуска в редакторе контента.",
|
||||||
url: "https://service.handhdc.ru",
|
url: "https://service.handhdc.ru/sso/launch",
|
||||||
launchUrl: "https://service.handhdc.ru/sso/launch",
|
launchUrl: "https://service.handhdc.ru/sso/launch",
|
||||||
accentColor: "#F7F8F4",
|
accentColor: "#F7F8F4",
|
||||||
fallbackGradient: "linear-gradient(135deg, rgba(247, 248, 244, 0.72), rgba(36, 37, 42, 0.9) 52%, #090B0F 88%)",
|
fallbackGradient: "linear-gradient(135deg, rgba(247, 248, 244, 0.72), rgba(36, 37, 42, 0.9) 52%, #090B0F 88%)",
|
||||||
|
|
@ -529,3 +530,10 @@ export function LauncherApp() {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function syncLauncherServiceLinks(data: LauncherData): LauncherData {
|
||||||
|
return {
|
||||||
|
...data,
|
||||||
|
services: data.services.map(syncServiceLaunchLink),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import type { Service } from "./types";
|
||||||
|
|
||||||
|
export function getServiceLaunchLink(service: Pick<Service, "url" | "launchUrl">): string {
|
||||||
|
return service.launchUrl?.trim() || service.url.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createServiceLaunchLinkPatch(value: string): Pick<Service, "url" | "launchUrl"> {
|
||||||
|
const launchLink = value.trim();
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: launchLink,
|
||||||
|
launchUrl: launchLink || null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function syncServiceLaunchLink(service: Service): Service {
|
||||||
|
return {
|
||||||
|
...service,
|
||||||
|
...createServiceLaunchLinkPatch(getServiceLaunchLink(service)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ import { computeEffectiveAccess } from "../../entities/access/computeEffectiveAc
|
||||||
import type { EffectiveAccessResult, ServiceAccessException, ServiceGrant } from "../../entities/access/types";
|
import type { EffectiveAccessResult, ServiceAccessException, ServiceGrant } from "../../entities/access/types";
|
||||||
import type { Client } from "../../entities/client/types";
|
import type { Client } from "../../entities/client/types";
|
||||||
import type { Invite } from "../../entities/invite/types";
|
import type { Invite } from "../../entities/invite/types";
|
||||||
|
import { getServiceLaunchLink } from "../../entities/service/links";
|
||||||
import type { LauncherServiceView, Service } from "../../entities/service/types";
|
import type { LauncherServiceView, Service } from "../../entities/service/types";
|
||||||
import type { SyncStatus } from "../../entities/sync/types";
|
import type { SyncStatus } from "../../entities/sync/types";
|
||||||
import type {
|
import type {
|
||||||
|
|
@ -217,7 +218,7 @@ export function buildLauncherServices(data: LauncherData, userId: string, active
|
||||||
status: service.status,
|
status: service.status,
|
||||||
userAccess: effectiveAccess.allowed ? ("allowed" as const) : ("denied" as const),
|
userAccess: effectiveAccess.allowed ? ("allowed" as const) : ("denied" as const),
|
||||||
appRole: effectiveAccess.appRole,
|
appRole: effectiveAccess.appRole,
|
||||||
openUrl: effectiveAccess.openEnabled ? service.launchUrl ?? service.url : null,
|
openUrl: effectiveAccess.openEnabled ? getServiceLaunchLink(service) || null : null,
|
||||||
accentColor: service.accentColor,
|
accentColor: service.accentColor,
|
||||||
media: {
|
media: {
|
||||||
icon: service.iconUrl,
|
icon: service.iconUrl,
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ export const mockServices: Service[] = [
|
||||||
description: "Сборка, запуск и мониторинг агентных workflow.",
|
description: "Сборка, запуск и мониторинг агентных workflow.",
|
||||||
fullDescription:
|
fullDescription:
|
||||||
"NodeDC используется для настройки агентных процессов, визуальной оркестрации, интеграций и runtime-мониторинга.",
|
"NodeDC используется для настройки агентных процессов, визуальной оркестрации, интеграций и runtime-мониторинга.",
|
||||||
url: "https://dev.handhdc.ru",
|
url: "https://dev.handhdc.ru/sso/launch",
|
||||||
launchUrl: "https://dev.handhdc.ru/sso/launch",
|
launchUrl: "https://dev.handhdc.ru/sso/launch",
|
||||||
accentColor: "#B5FF5A",
|
accentColor: "#B5FF5A",
|
||||||
fallbackGradient: "linear-gradient(128deg, rgba(181, 255, 90, 0.84), rgba(37, 58, 36, 0.86) 42%, #0A0D10 82%)",
|
fallbackGradient: "linear-gradient(128deg, rgba(181, 255, 90, 0.84), rgba(37, 58, 36, 0.86) 42%, #0A0D10 82%)",
|
||||||
|
|
@ -168,7 +168,7 @@ export const mockServices: Service[] = [
|
||||||
subtitle: "Операционный слой",
|
subtitle: "Операционный слой",
|
||||||
description: "Задачи, контуры предприятия, процессы и AI-функции поверх задачника.",
|
description: "Задачи, контуры предприятия, процессы и AI-функции поверх задачника.",
|
||||||
fullDescription: "Task Manager основан на архитектуре Plane и расширен AI-функциями NODE.DC.",
|
fullDescription: "Task Manager основан на архитектуре Plane и расширен AI-функциями NODE.DC.",
|
||||||
url: "https://tasks.handhdc.ru",
|
url: "https://tasks.handhdc.ru/sso/launch",
|
||||||
launchUrl: "https://tasks.handhdc.ru/sso/launch",
|
launchUrl: "https://tasks.handhdc.ru/sso/launch",
|
||||||
accentColor: "#D7C8FF",
|
accentColor: "#D7C8FF",
|
||||||
fallbackGradient: "linear-gradient(132deg, rgba(215, 200, 255, 0.82), rgba(51, 41, 79, 0.9) 46%, #0B0D10 84%)",
|
fallbackGradient: "linear-gradient(132deg, rgba(215, 200, 255, 0.82), rgba(51, 41, 79, 0.9) 46%, #0B0D10 84%)",
|
||||||
|
|
@ -186,7 +186,7 @@ export const mockServices: Service[] = [
|
||||||
subtitle: "Бухгалтерский ассистент",
|
subtitle: "Бухгалтерский ассистент",
|
||||||
description: "Вопросы к 1С, точные выборки и доказательная навигация по данным.",
|
description: "Вопросы к 1С, точные выборки и доказательная навигация по данным.",
|
||||||
fullDescription: "Ассистент для бухгалтерских запросов, анализа операций, остатков и документов.",
|
fullDescription: "Ассистент для бухгалтерских запросов, анализа операций, остатков и документов.",
|
||||||
url: "https://1c.handhdc.ru",
|
url: "https://1c.handhdc.ru/sso/launch",
|
||||||
launchUrl: "https://1c.handhdc.ru/sso/launch",
|
launchUrl: "https://1c.handhdc.ru/sso/launch",
|
||||||
accentColor: "#8FD7FF",
|
accentColor: "#8FD7FF",
|
||||||
fallbackGradient: "linear-gradient(126deg, rgba(143, 215, 255, 0.8), rgba(32, 61, 80, 0.9) 44%, #080B0F 84%)",
|
fallbackGradient: "linear-gradient(126deg, rgba(143, 215, 255, 0.8), rgba(32, 61, 80, 0.9) 44%, #080B0F 84%)",
|
||||||
|
|
@ -204,7 +204,7 @@ export const mockServices: Service[] = [
|
||||||
subtitle: "Госзакупки и тендеры",
|
subtitle: "Госзакупки и тендеры",
|
||||||
description: "Поиск, анализ и подготовка тендерных решений.",
|
description: "Поиск, анализ и подготовка тендерных решений.",
|
||||||
fullDescription: "Сервис собирает тендерные данные, строит выжимку рисков и помогает подготовить пакет участия.",
|
fullDescription: "Сервис собирает тендерные данные, строит выжимку рисков и помогает подготовить пакет участия.",
|
||||||
url: "https://tender.handhdc.ru",
|
url: "https://tender.handhdc.ru/sso/launch",
|
||||||
launchUrl: "https://tender.handhdc.ru/sso/launch",
|
launchUrl: "https://tender.handhdc.ru/sso/launch",
|
||||||
accentColor: "#FFD166",
|
accentColor: "#FFD166",
|
||||||
fallbackGradient: "linear-gradient(135deg, rgba(255, 209, 102, 0.84), rgba(74, 53, 19, 0.92) 42%, #0B0D10 86%)",
|
fallbackGradient: "linear-gradient(135deg, rgba(255, 209, 102, 0.84), rgba(74, 53, 19, 0.92) 42%, #0B0D10 86%)",
|
||||||
|
|
@ -222,7 +222,7 @@ export const mockServices: Service[] = [
|
||||||
subtitle: "3D и пространственные данные",
|
subtitle: "3D и пространственные данные",
|
||||||
description: "Просмотр цифровых двойников, карт и объектных сцен.",
|
description: "Просмотр цифровых двойников, карт и объектных сцен.",
|
||||||
fullDescription: "Витрина геометрии, объектов, слоёв и статусов инфраструктуры.",
|
fullDescription: "Витрина геометрии, объектов, слоёв и статусов инфраструктуры.",
|
||||||
url: "https://twin.handhdc.ru",
|
url: "https://twin.handhdc.ru/sso/launch",
|
||||||
launchUrl: "https://twin.handhdc.ru/sso/launch",
|
launchUrl: "https://twin.handhdc.ru/sso/launch",
|
||||||
accentColor: "#76E4F7",
|
accentColor: "#76E4F7",
|
||||||
fallbackGradient: "linear-gradient(140deg, rgba(118, 228, 247, 0.82), rgba(23, 69, 87, 0.92) 47%, #080B0F 86%)",
|
fallbackGradient: "linear-gradient(140deg, rgba(118, 228, 247, 0.82), rgba(23, 69, 87, 0.92) 47%, #080B0F 86%)",
|
||||||
|
|
@ -240,7 +240,7 @@ export const mockServices: Service[] = [
|
||||||
subtitle: "Будущие модули",
|
subtitle: "Будущие модули",
|
||||||
description: "Скрытый каталог модулей для root-admin preview.",
|
description: "Скрытый каталог модулей для root-admin preview.",
|
||||||
fullDescription: "Площадка для будущих цифровых модулей NODE.DC.",
|
fullDescription: "Площадка для будущих цифровых модулей NODE.DC.",
|
||||||
url: "https://dm.handhdc.ru",
|
url: "https://dm.handhdc.ru/sso/launch",
|
||||||
launchUrl: "https://dm.handhdc.ru/sso/launch",
|
launchUrl: "https://dm.handhdc.ru/sso/launch",
|
||||||
accentColor: "#FF9AC2",
|
accentColor: "#FF9AC2",
|
||||||
fallbackGradient: "linear-gradient(135deg, rgba(255, 154, 194, 0.78), rgba(76, 41, 64, 0.9) 44%, #090B0F 86%)",
|
fallbackGradient: "linear-gradient(135deg, rgba(255, 154, 194, 0.78), rgba(76, 41, 64, 0.9) 44%, #090B0F 86%)",
|
||||||
|
|
@ -259,7 +259,7 @@ export const mockServices: Service[] = [
|
||||||
description: "Отключённый сервис для проверки диагностики root-admin.",
|
description: "Отключённый сервис для проверки диагностики root-admin.",
|
||||||
fullDescription: "Не показывается обычным пользователям, виден root-admin в каталоге.",
|
fullDescription: "Не показывается обычным пользователям, виден root-admin в каталоге.",
|
||||||
url: "https://internal.handhdc.ru",
|
url: "https://internal.handhdc.ru",
|
||||||
launchUrl: null,
|
launchUrl: "https://internal.handhdc.ru",
|
||||||
accentColor: "#F97373",
|
accentColor: "#F97373",
|
||||||
fallbackGradient: "linear-gradient(135deg, rgba(249, 115, 115, 0.78), rgba(73, 32, 32, 0.92) 43%, #090B0F 86%)",
|
fallbackGradient: "linear-gradient(135deg, rgba(249, 115, 115, 0.78), rgba(73, 32, 32, 0.92) 43%, #090B0F 86%)",
|
||||||
status: "disabled",
|
status: "disabled",
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ import {
|
||||||
import type { ServiceAppRole } from "../../entities/access/types";
|
import type { ServiceAppRole } from "../../entities/access/types";
|
||||||
import type { Client, ClientStatus, ClientType } from "../../entities/client/types";
|
import type { Client, ClientStatus, ClientType } from "../../entities/client/types";
|
||||||
import type { Invite, InviteStatus } from "../../entities/invite/types";
|
import type { Invite, InviteStatus } from "../../entities/invite/types";
|
||||||
|
import { createServiceLaunchLinkPatch, getServiceLaunchLink } from "../../entities/service/links";
|
||||||
import type { MediaKind, Service, ServiceMediaSource, ServiceStatus } from "../../entities/service/types";
|
import type { MediaKind, Service, ServiceMediaSource, ServiceStatus } from "../../entities/service/types";
|
||||||
import type { SyncState, SyncStatus } from "../../entities/sync/types";
|
import type { SyncState, SyncStatus } from "../../entities/sync/types";
|
||||||
import type {
|
import type {
|
||||||
|
|
@ -875,7 +876,7 @@ function ServicesSection({
|
||||||
<th>Сервис</th>
|
<th>Сервис</th>
|
||||||
<th>Slug</th>
|
<th>Slug</th>
|
||||||
<th>Статус</th>
|
<th>Статус</th>
|
||||||
<th>URL</th>
|
<th>Ссылка запуска</th>
|
||||||
<th>Authentik</th>
|
<th>Authentik</th>
|
||||||
<th aria-label="Редактирование" />
|
<th aria-label="Редактирование" />
|
||||||
<th aria-label="Порядок" />
|
<th aria-label="Порядок" />
|
||||||
|
|
@ -1007,9 +1008,9 @@ function ServiceTableCells({
|
||||||
<td>
|
<td>
|
||||||
<input
|
<input
|
||||||
className="admin-table-input"
|
className="admin-table-input"
|
||||||
value={service.url}
|
value={getServiceLaunchLink(service)}
|
||||||
onChange={(event) => onUpdateService(service.id, { url: event.target.value })}
|
onChange={(event) => onUpdateService(service.id, createServiceLaunchLinkPatch(event.target.value))}
|
||||||
aria-label={`URL сервиса ${service.title}`}
|
aria-label={`Ссылка запуска сервиса ${service.title}`}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -1262,7 +1263,10 @@ function ServiceContentModal({
|
||||||
<span>
|
<span>
|
||||||
<Link2 size={14} /> Ссылка запуска
|
<Link2 size={14} /> Ссылка запуска
|
||||||
</span>
|
</span>
|
||||||
<input value={draft.launchUrl ?? ""} onChange={(event) => update("launchUrl", event.target.value || null)} />
|
<input
|
||||||
|
value={getServiceLaunchLink(draft)}
|
||||||
|
onChange={(event) => setDraft((current) => ({ ...current, ...createServiceLaunchLinkPatch(event.target.value) }))}
|
||||||
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<MediaSourceField
|
<MediaSourceField
|
||||||
|
|
@ -1331,16 +1335,17 @@ function ServiceContentModal({
|
||||||
subtitle: draft.subtitle,
|
subtitle: draft.subtitle,
|
||||||
description: draft.description,
|
description: draft.description,
|
||||||
fullDescription: draft.fullDescription,
|
fullDescription: draft.fullDescription,
|
||||||
launchUrl: draft.launchUrl,
|
url: draft.url,
|
||||||
coverImageUrl: draft.coverImageUrl,
|
launchUrl: draft.launchUrl,
|
||||||
coverMediaKind: draft.coverMediaKind,
|
coverImageUrl: draft.coverImageUrl,
|
||||||
coverMediaSource: draft.coverMediaSource,
|
coverMediaKind: draft.coverMediaKind,
|
||||||
coverMediaFileName: draft.coverMediaFileName,
|
coverMediaSource: draft.coverMediaSource,
|
||||||
ambientVideoUrl: draft.ambientVideoUrl,
|
coverMediaFileName: draft.coverMediaFileName,
|
||||||
ambientMediaKind: draft.ambientMediaKind,
|
ambientVideoUrl: draft.ambientVideoUrl,
|
||||||
ambientMediaSource: draft.ambientMediaSource,
|
ambientMediaKind: draft.ambientMediaKind,
|
||||||
ambientMediaFileName: draft.ambientMediaFileName,
|
ambientMediaSource: draft.ambientMediaSource,
|
||||||
})
|
ambientMediaFileName: draft.ambientMediaFileName,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{uploadingSlot ? "Сохраняем файл" : "Сохранить"}
|
{uploadingSlot ? "Сохраняем файл" : "Сохранить"}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue