@weavix/cli 0.1.0-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -0
- package/build/index.js +2568 -0
- package/build/templates/.arcignore +35 -0
- package/build/templates/_shared/.arcignore +20 -0
- package/build/templates/_shared/.prettierrc.js +6 -0
- package/build/templates/_shared/.stylelintrc +3 -0
- package/build/templates/_shared/eslint.config.js +12 -0
- package/build/templates/_shared/manifest.schema.json +438 -0
- package/build/templates/_shared/marketplace/README.md +12 -0
- package/build/templates/_shared/npmrc.template +2 -0
- package/build/templates/_shared/package.json +69 -0
- package/build/templates/_shared/public/README.md +12 -0
- package/build/templates/_shared/public/fonts/ys-text-display-wide-110.woff +0 -0
- package/build/templates/_shared/public/fonts/ys-text-display-wide-110.woff2 +0 -0
- package/build/templates/_shared/src/main.tsx +21 -0
- package/build/templates/_shared/src/reset.css +55 -0
- package/build/templates/_shared/src/styles-360.scss +81 -0
- package/build/templates/_shared/src/styles-gravity.scss +249 -0
- package/build/templates/_shared/src/vite-env.d.ts +2 -0
- package/build/templates/_shared/tsconfig.json +16 -0
- package/build/templates/_shared/vite.config.ts +66 -0
- package/build/templates/attachment.viewer.action/index.html +14 -0
- package/build/templates/attachment.viewer.action/src/App.tsx +59 -0
- package/build/templates/default/index.html +14 -0
- package/build/templates/default/src/App.tsx +10 -0
- package/build/templates/goal.action/index.html +14 -0
- package/build/templates/goal.action/src/App.tsx +39 -0
- package/build/templates/issue.action/index.html +14 -0
- package/build/templates/issue.action/src/App.tsx +36 -0
- package/build/templates/issue.block/index.html +14 -0
- package/build/templates/issue.block/src/App.tsx +34 -0
- package/build/templates/issue.comment.action/index.html +14 -0
- package/build/templates/issue.comment.action/src/App.tsx +33 -0
- package/build/templates/issue.floatingbottom.action/index.html +14 -0
- package/build/templates/issue.floatingbottom.action/src/App.tsx +28 -0
- package/build/templates/issue.tab/index.html +14 -0
- package/build/templates/issue.tab/src/App.tsx +36 -0
- package/build/templates/navigation/index.html +14 -0
- package/build/templates/navigation/src/App.tsx +15 -0
- package/build/templates/portfolio.action/index.html +14 -0
- package/build/templates/portfolio.action/src/App.tsx +44 -0
- package/build/templates/project.action/index.html +14 -0
- package/build/templates/project.action/src/App.tsx +44 -0
- package/build/templates/trigger.action/index.html +14 -0
- package/build/templates/trigger.action/src/App.scss +46 -0
- package/build/templates/trigger.action/src/App.tsx +153 -0
- package/package.json +35 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Card, DefinitionList, ThemeProvider, Text as Typography } from '@gravity-ui/uikit';
|
|
2
|
+
import { getField, useTrackerPluginContext } from '@yandex-data-ui/tracker-plugin-sdk-react';
|
|
3
|
+
|
|
4
|
+
const App = () => {
|
|
5
|
+
const { theme, slotContext } = useTrackerPluginContext<'issue.action'>();
|
|
6
|
+
|
|
7
|
+
if (!slotContext) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const summary = getField<string>(slotContext, 'summary', 'Без названия');
|
|
12
|
+
const priority = getField<string>(slotContext, 'priority.display', 'Не указан');
|
|
13
|
+
const assignee = getField<string>(slotContext, 'assignee.display', 'Не назначен');
|
|
14
|
+
const status = getField<string>(slotContext, 'status.display', 'Не указан');
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<ThemeProvider theme={theme}>
|
|
18
|
+
<div style={{ width: '800px', padding: '50px' }}>
|
|
19
|
+
<Card style={{ padding: '20px' }}>
|
|
20
|
+
<Typography variant="header-1" as="div" style={{ marginBottom: '16px' }}>
|
|
21
|
+
Текущий контекст в проде
|
|
22
|
+
</Typography>
|
|
23
|
+
<DefinitionList>
|
|
24
|
+
<DefinitionList.Item name="Ключ">{slotContext.key}</DefinitionList.Item>
|
|
25
|
+
<DefinitionList.Item name="Приоритет">{priority}</DefinitionList.Item>
|
|
26
|
+
<DefinitionList.Item name="Исполнитель">{assignee}</DefinitionList.Item>
|
|
27
|
+
<DefinitionList.Item name="Статус">{status}</DefinitionList.Item>
|
|
28
|
+
<DefinitionList.Item name="Название">{summary}</DefinitionList.Item>
|
|
29
|
+
</DefinitionList>
|
|
30
|
+
</Card>
|
|
31
|
+
</div>
|
|
32
|
+
</ThemeProvider>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default App;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<meta name="description" content="Web site created using vite" />
|
|
7
|
+
<title>Issue Under Description Plugin</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body class="g-root g-root_theme_dark">
|
|
10
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Card, DefinitionList, ThemeProvider, Text as Typography } from '@gravity-ui/uikit';
|
|
2
|
+
import { getField, useTrackerPluginContext } from '@yandex-data-ui/tracker-plugin-sdk-react';
|
|
3
|
+
|
|
4
|
+
const App = () => {
|
|
5
|
+
const { theme, slotContext } = useTrackerPluginContext<'issue.block'>();
|
|
6
|
+
|
|
7
|
+
if (!slotContext) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const summary = getField<string>(slotContext, 'summary', 'Без названия');
|
|
12
|
+
const priority = getField<string>(slotContext, 'priority.display', 'Не указан');
|
|
13
|
+
const assignee = getField<string>(slotContext, 'assignee.display', 'Не назначен');
|
|
14
|
+
const status = getField<string>(slotContext, 'status.display', 'Не указан');
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<ThemeProvider theme={theme}>
|
|
18
|
+
<Card style={{ padding: '20px' }}>
|
|
19
|
+
<Typography variant="header-1" as="div" style={{ marginBottom: '16px' }}>
|
|
20
|
+
Текущий контекст в проде
|
|
21
|
+
</Typography>
|
|
22
|
+
<DefinitionList>
|
|
23
|
+
<DefinitionList.Item name="Ключ">{slotContext.key}</DefinitionList.Item>
|
|
24
|
+
<DefinitionList.Item name="Приоритет">{priority}</DefinitionList.Item>
|
|
25
|
+
<DefinitionList.Item name="Исполнитель">{assignee}</DefinitionList.Item>
|
|
26
|
+
<DefinitionList.Item name="Статус">{status}</DefinitionList.Item>
|
|
27
|
+
<DefinitionList.Item name="Название">{summary}</DefinitionList.Item>
|
|
28
|
+
</DefinitionList>
|
|
29
|
+
</Card>
|
|
30
|
+
</ThemeProvider>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default App;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<meta name="description" content="Web site created using vite" />
|
|
7
|
+
<title>Issue Comment Actions Plugin</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body class="g-root g-root_theme_dark">
|
|
10
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Card, DefinitionList, ThemeProvider, Text as Typography } from '@gravity-ui/uikit';
|
|
2
|
+
import { useTrackerPluginContext } from '@yandex-data-ui/tracker-plugin-sdk-react';
|
|
3
|
+
|
|
4
|
+
const App = () => {
|
|
5
|
+
const { theme, slotContext } = useTrackerPluginContext<'issue.comment.action'>();
|
|
6
|
+
|
|
7
|
+
if (!slotContext) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<ThemeProvider theme={theme}>
|
|
13
|
+
<div style={{ width: '800px', padding: '50px' }}>
|
|
14
|
+
<Card style={{ padding: '20px' }}>
|
|
15
|
+
<Typography variant="header-1" as="div" style={{ marginBottom: '16px' }}>
|
|
16
|
+
Текущий контекст в проде
|
|
17
|
+
</Typography>
|
|
18
|
+
<DefinitionList>
|
|
19
|
+
<DefinitionList.Item name="ID">{slotContext.id}</DefinitionList.Item>
|
|
20
|
+
<DefinitionList.Item name="Тип">{slotContext.type}</DefinitionList.Item>
|
|
21
|
+
<DefinitionList.Item name="Канал">{slotContext.transport}</DefinitionList.Item>
|
|
22
|
+
<DefinitionList.Item name="Создан">{slotContext.createdAt}</DefinitionList.Item>
|
|
23
|
+
<DefinitionList.Item name="Обновлён">{slotContext.updatedAt ?? '—'}</DefinitionList.Item>
|
|
24
|
+
<DefinitionList.Item name="Текст">{slotContext.text}</DefinitionList.Item>
|
|
25
|
+
<DefinitionList.Item name="Текст">{slotContext.email}</DefinitionList.Item>
|
|
26
|
+
</DefinitionList>
|
|
27
|
+
</Card>
|
|
28
|
+
</div>
|
|
29
|
+
</ThemeProvider>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default App;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<meta name="description" content="Web site created using vite" />
|
|
7
|
+
<title>Issue FloatingBottom Actions Plugin</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body class="g-root g-root_theme_dark">
|
|
10
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Card, DefinitionList, ThemeProvider, Text as Typography } from '@gravity-ui/uikit';
|
|
2
|
+
import { useTrackerPluginContext } from '@yandex-data-ui/tracker-plugin-sdk-react';
|
|
3
|
+
|
|
4
|
+
const App = () => {
|
|
5
|
+
const { theme, slotContext, isYateam, userId } = useTrackerPluginContext<'issue.floatingbottom.action'>();
|
|
6
|
+
|
|
7
|
+
if (!slotContext) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<ThemeProvider theme={theme}>
|
|
13
|
+
<div style={{ width: '800px', padding: '50px' }}>
|
|
14
|
+
<Card style={{ padding: '20px' }}>
|
|
15
|
+
<Typography variant="header-1" as="div" style={{ marginBottom: '16px' }}>
|
|
16
|
+
Текущий контекст в проде
|
|
17
|
+
</Typography>
|
|
18
|
+
<DefinitionList>
|
|
19
|
+
<DefinitionList.Item name="Id пользователя">{userId}</DefinitionList.Item>
|
|
20
|
+
<DefinitionList.Item name="Is yataem">{isYateam ? 'Да' : 'Нет'}</DefinitionList.Item>
|
|
21
|
+
</DefinitionList>
|
|
22
|
+
</Card>
|
|
23
|
+
</div>
|
|
24
|
+
</ThemeProvider>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default App;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<meta name="description" content="Web site created using vite" />
|
|
7
|
+
<title>Issue Tab Plugin</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body class="g-root g-root_theme_dark">
|
|
10
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Card, DefinitionList, ThemeProvider, Text as Typography } from '@gravity-ui/uikit';
|
|
2
|
+
import { getField, useTrackerPluginContext } from '@yandex-data-ui/tracker-plugin-sdk-react';
|
|
3
|
+
|
|
4
|
+
const App = () => {
|
|
5
|
+
const { theme, slotContext } = useTrackerPluginContext<'issue.tab'>();
|
|
6
|
+
|
|
7
|
+
if (!slotContext) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const summary = getField<string>(slotContext, 'summary', 'Без названия');
|
|
12
|
+
const priority = getField<string>(slotContext, 'priority.display', 'Не указан');
|
|
13
|
+
const assignee = getField<string>(slotContext, 'assignee.display', 'Не назначен');
|
|
14
|
+
const status = getField<string>(slotContext, 'status.display', 'Не указан');
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<ThemeProvider theme={theme}>
|
|
18
|
+
<div style={{ padding: '50px' }}>
|
|
19
|
+
<Card style={{ padding: '20px' }}>
|
|
20
|
+
<Typography variant="header-1" as="div" style={{ marginBottom: '16px' }}>
|
|
21
|
+
Текущий контекст в проде
|
|
22
|
+
</Typography>
|
|
23
|
+
<DefinitionList>
|
|
24
|
+
<DefinitionList.Item name="Ключ">{slotContext.key}</DefinitionList.Item>
|
|
25
|
+
<DefinitionList.Item name="Приоритет">{priority}</DefinitionList.Item>
|
|
26
|
+
<DefinitionList.Item name="Исполнитель">{assignee}</DefinitionList.Item>
|
|
27
|
+
<DefinitionList.Item name="Статус">{status}</DefinitionList.Item>
|
|
28
|
+
<DefinitionList.Item name="Название">{summary}</DefinitionList.Item>
|
|
29
|
+
</DefinitionList>
|
|
30
|
+
</Card>
|
|
31
|
+
</div>
|
|
32
|
+
</ThemeProvider>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default App;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<meta name="description" content="Web site created using vite" />
|
|
7
|
+
<title>Navigation Plugin</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body class="g-root g-root_theme_dark">
|
|
10
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ThemeProvider } from '@gravity-ui/uikit';
|
|
2
|
+
import { useTrackerPluginContext } from '@yandex-data-ui/tracker-plugin-sdk-react';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const App = () => {
|
|
6
|
+
const { theme } = useTrackerPluginContext<'navigation'>();
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<ThemeProvider theme={theme}>
|
|
10
|
+
Yout plugin code here
|
|
11
|
+
</ThemeProvider>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default App;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<meta name="description" content="Web site created using vite" />
|
|
7
|
+
<title>Project Actions Plugin</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body class="g-root g-root_theme_dark">
|
|
10
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Card, DefinitionList, ThemeProvider, Text as Typography } from '@gravity-ui/uikit';
|
|
2
|
+
import { getField, useTrackerPluginContext } from '@yandex-data-ui/tracker-plugin-sdk-react';
|
|
3
|
+
|
|
4
|
+
const App = () => {
|
|
5
|
+
const { theme, slotContext } = useTrackerPluginContext<'portfolio.action'>();
|
|
6
|
+
|
|
7
|
+
if (!slotContext) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const summary = getField<string>(slotContext, 'fields.summary.value', 'Без названия');
|
|
12
|
+
const description = getField<string>(
|
|
13
|
+
slotContext,
|
|
14
|
+
'fields.description.value',
|
|
15
|
+
'Пустое описание',
|
|
16
|
+
);
|
|
17
|
+
const status = getField<string>(slotContext, 'fields.entityStatus.value', 'Не указан');
|
|
18
|
+
const progress = getField<{ total: number; closed: number }>(slotContext, 'progress', {
|
|
19
|
+
total: 0,
|
|
20
|
+
closed: 0,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<ThemeProvider theme={theme}>
|
|
25
|
+
<div style={{ width: '800px', padding: '50px' }}>
|
|
26
|
+
<Card style={{ padding: '20px' }}>
|
|
27
|
+
<Typography variant="header-1" as="div" style={{ marginBottom: '16px' }}>
|
|
28
|
+
Текущий контекст в проде
|
|
29
|
+
</Typography>
|
|
30
|
+
<DefinitionList>
|
|
31
|
+
<DefinitionList.Item name="Название">{summary}</DefinitionList.Item>
|
|
32
|
+
<DefinitionList.Item name="Описание">{description}</DefinitionList.Item>
|
|
33
|
+
<DefinitionList.Item name="Статус">{status}</DefinitionList.Item>
|
|
34
|
+
<DefinitionList.Item name="Прогресс">
|
|
35
|
+
{progress?.closed}/{progress?.total}
|
|
36
|
+
</DefinitionList.Item>
|
|
37
|
+
</DefinitionList>
|
|
38
|
+
</Card>
|
|
39
|
+
</div>
|
|
40
|
+
</ThemeProvider>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default App;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<meta name="description" content="Web site created using vite" />
|
|
7
|
+
<title>Project Actions Plugin</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body class="g-root g-root_theme_dark">
|
|
10
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Card, DefinitionList, ThemeProvider, Text as Typography } from '@gravity-ui/uikit';
|
|
2
|
+
import { getField, useTrackerPluginContext } from '@yandex-data-ui/tracker-plugin-sdk-react';
|
|
3
|
+
|
|
4
|
+
const App = () => {
|
|
5
|
+
const { theme, slotContext } = useTrackerPluginContext<'project.action'>();
|
|
6
|
+
|
|
7
|
+
if (!slotContext) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const summary = getField<string>(slotContext, 'fields.summary.value', 'Без названия');
|
|
12
|
+
const description = getField<string>(
|
|
13
|
+
slotContext,
|
|
14
|
+
'fields.description.value',
|
|
15
|
+
'Пустое описание',
|
|
16
|
+
);
|
|
17
|
+
const status = getField<string>(slotContext, 'fields.entityStatus.value', 'Не указан');
|
|
18
|
+
const progress = getField<{ total: number; closed: number }>(slotContext, 'progress', {
|
|
19
|
+
total: 0,
|
|
20
|
+
closed: 0,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<ThemeProvider theme={theme}>
|
|
25
|
+
<div style={{ width: '800px', padding: '50px' }}>
|
|
26
|
+
<Card style={{ padding: '20px' }}>
|
|
27
|
+
<Typography variant="header-1" as="div" style={{ marginBottom: '16px' }}>
|
|
28
|
+
Текущий контекст в проде
|
|
29
|
+
</Typography>
|
|
30
|
+
<DefinitionList>
|
|
31
|
+
<DefinitionList.Item name="Название">{summary}</DefinitionList.Item>
|
|
32
|
+
<DefinitionList.Item name="Описание">{description}</DefinitionList.Item>
|
|
33
|
+
<DefinitionList.Item name="Статус">{status}</DefinitionList.Item>
|
|
34
|
+
<DefinitionList.Item name="Прогресс">
|
|
35
|
+
{progress?.closed}/{progress?.total}
|
|
36
|
+
</DefinitionList.Item>
|
|
37
|
+
</DefinitionList>
|
|
38
|
+
</Card>
|
|
39
|
+
</div>
|
|
40
|
+
</ThemeProvider>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default App;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<meta name="description" content="Web site created using vite" />
|
|
7
|
+
<title>Trigger Actions Plugin</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body class="g-root g-root_theme_dark">
|
|
10
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
.app {
|
|
2
|
+
&__container {
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
gap: 16px;
|
|
6
|
+
padding: 16px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
&__slot-title {
|
|
10
|
+
margin-bottom: 8px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
&__context-card {
|
|
14
|
+
padding: 16px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
&__context-title {
|
|
18
|
+
margin-bottom: 12px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
&__form-field {
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
gap: 8px;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&__field-label {
|
|
28
|
+
font-weight: 500;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&__queue-value {
|
|
32
|
+
color: var(--g-color-text-secondary);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&__checkboxes {
|
|
36
|
+
display: flex;
|
|
37
|
+
flex-direction: column;
|
|
38
|
+
gap: 8px;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&__body-preview {
|
|
42
|
+
color: var(--g-color-text-secondary);
|
|
43
|
+
font-family: var(--g-font-family-mono);
|
|
44
|
+
font-size: 12px;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { Card, Checkbox, DefinitionList, Text, TextInput, ThemeProvider } from '@gravity-ui/uikit';
|
|
4
|
+
import {
|
|
5
|
+
TriggerActionData,
|
|
6
|
+
useTrackerPluginContext,
|
|
7
|
+
} from '@yandex-data-ui/tracker-plugin-sdk-react';
|
|
8
|
+
import block from 'bem-cn-lite';
|
|
9
|
+
|
|
10
|
+
import './App.scss';
|
|
11
|
+
|
|
12
|
+
const b = block('app');
|
|
13
|
+
|
|
14
|
+
const WEBHOOK_SITE_BASE = 'https://webhook.site';
|
|
15
|
+
|
|
16
|
+
const SLOT_LABELS: Record<string, string> = {
|
|
17
|
+
'trigger.create.action': 'Создание действия',
|
|
18
|
+
'trigger.edit.action': 'Редактирование действия',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function parseWebhookSiteIdFromEndpoint(endpoint: string | undefined): string {
|
|
22
|
+
if (!endpoint) return '';
|
|
23
|
+
try {
|
|
24
|
+
const url = new URL(endpoint);
|
|
25
|
+
if (url.origin !== 'https://webhook.site' && !url.hostname.endsWith('webhook.site'))
|
|
26
|
+
return '';
|
|
27
|
+
return url.pathname.replace(/^\//, '').split('/')[0] ?? '';
|
|
28
|
+
} catch {
|
|
29
|
+
return '';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const BODY_ISSUE_KEY = '{{issue.key}}';
|
|
34
|
+
const BODY_QUEUE = '{{issue.queue}}';
|
|
35
|
+
|
|
36
|
+
function buildBodyFromOptions(addIssueKey: boolean, addQueue: boolean): string {
|
|
37
|
+
const obj: Record<string, string> = {};
|
|
38
|
+
if (addIssueKey) obj.issue = BODY_ISSUE_KEY;
|
|
39
|
+
if (addQueue) obj.queue = BODY_QUEUE;
|
|
40
|
+
return Object.keys(obj).length > 0 ? JSON.stringify(obj) : '{}';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function parseBodyOptions(body: string | undefined): { addIssueKey: boolean; addQueue: boolean } {
|
|
44
|
+
if (!body?.trim()) return { addIssueKey: false, addQueue: false };
|
|
45
|
+
try {
|
|
46
|
+
const parsed = JSON.parse(body) as Record<string, unknown>;
|
|
47
|
+
const addIssueKey =
|
|
48
|
+
typeof parsed?.issue === 'string' && parsed.issue.includes(BODY_ISSUE_KEY);
|
|
49
|
+
const addQueue = typeof parsed?.queue === 'string' && parsed.queue.includes(BODY_QUEUE);
|
|
50
|
+
return { addIssueKey, addQueue };
|
|
51
|
+
} catch {
|
|
52
|
+
return { addIssueKey: false, addQueue: false };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const App = () => {
|
|
57
|
+
const { theme, registerHandler, slot, slotContext } = useTrackerPluginContext<
|
|
58
|
+
'trigger.create.action' | 'trigger.edit.action'
|
|
59
|
+
>();
|
|
60
|
+
|
|
61
|
+
const [webhookSiteId, setWebhookSiteId] = useState<string>('');
|
|
62
|
+
const [addIssueKey, setAddIssueKey] = useState<boolean>(true);
|
|
63
|
+
const [addQueue, setAddQueue] = useState<boolean>(true);
|
|
64
|
+
|
|
65
|
+
// При редактировании подставляем данные из сохранённого экшена (слот trigger.edit.action)
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (slotContext && 'data' in slotContext) {
|
|
68
|
+
const data = slotContext.data as { endpoint?: string; body?: string };
|
|
69
|
+
const siteId = parseWebhookSiteIdFromEndpoint(data.endpoint);
|
|
70
|
+
if (siteId) setWebhookSiteId(siteId);
|
|
71
|
+
const { addIssueKey: savedIssueKey, addQueue: savedQueue } = parseBodyOptions(
|
|
72
|
+
data.body ?? undefined,
|
|
73
|
+
);
|
|
74
|
+
setAddIssueKey(savedIssueKey);
|
|
75
|
+
setAddQueue(savedQueue);
|
|
76
|
+
}
|
|
77
|
+
}, [slot, slotContext]);
|
|
78
|
+
|
|
79
|
+
const getFormData = (): TriggerActionData => ({
|
|
80
|
+
method: 'POST',
|
|
81
|
+
endpoint: webhookSiteId ? `${WEBHOOK_SITE_BASE}/${webhookSiteId}` : undefined,
|
|
82
|
+
contentType: 'application/json; charset=UTF-8',
|
|
83
|
+
body: buildBodyFromOptions(addIssueKey, addQueue),
|
|
84
|
+
authContext: { type: 'noauth' },
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
registerHandler('getData', getFormData);
|
|
88
|
+
|
|
89
|
+
const slotTitle = SLOT_LABELS[slot] ?? slot;
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<ThemeProvider theme={theme}>
|
|
93
|
+
<div className={b('container')}>
|
|
94
|
+
<Text variant="header-1" className={b('slot-title')}>
|
|
95
|
+
{slotTitle}
|
|
96
|
+
</Text>
|
|
97
|
+
|
|
98
|
+
{slotContext && (
|
|
99
|
+
<Card className={b('context-card')}>
|
|
100
|
+
<Text variant="subheader-2" className={b('context-title')}>
|
|
101
|
+
Контекст
|
|
102
|
+
</Text>
|
|
103
|
+
<DefinitionList>
|
|
104
|
+
<DefinitionList.Item name="Текущая очередь">
|
|
105
|
+
{String(slotContext.queue ?? '—')}
|
|
106
|
+
</DefinitionList.Item>
|
|
107
|
+
</DefinitionList>
|
|
108
|
+
</Card>
|
|
109
|
+
)}
|
|
110
|
+
|
|
111
|
+
<div className={b('form-field')}>
|
|
112
|
+
<Text variant="subheader-1" className={b('field-label')}>
|
|
113
|
+
ID сайта на webhook.site
|
|
114
|
+
</Text>
|
|
115
|
+
<TextInput
|
|
116
|
+
value={webhookSiteId}
|
|
117
|
+
onUpdate={setWebhookSiteId}
|
|
118
|
+
placeholder="Вставьте ID из webhook.site"
|
|
119
|
+
size="l"
|
|
120
|
+
/>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<div className={b('form-field')}>
|
|
124
|
+
<Text variant="subheader-1" className={b('field-label')}>
|
|
125
|
+
Включить в тело запроса
|
|
126
|
+
</Text>
|
|
127
|
+
<div className={b('checkboxes')}>
|
|
128
|
+
<Checkbox checked={addIssueKey} onUpdate={setAddIssueKey} size="l">
|
|
129
|
+
<Text>Добавить ключ задачи</Text>
|
|
130
|
+
</Checkbox>
|
|
131
|
+
<Checkbox checked={addQueue} onUpdate={setAddQueue} size="l">
|
|
132
|
+
<Text>Добавить очередь</Text>
|
|
133
|
+
</Checkbox>
|
|
134
|
+
</div>
|
|
135
|
+
<Text variant="body-2" className={b('body-preview')}>
|
|
136
|
+
Шаблон: {buildBodyFromOptions(addIssueKey, addQueue)}
|
|
137
|
+
</Text>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
<div className={b('form-field')}>
|
|
141
|
+
<Text variant="subheader-1" className={b('field-label')}>
|
|
142
|
+
Текущая очередь
|
|
143
|
+
</Text>
|
|
144
|
+
<Text variant="body-2" className={b('queue-value')}>
|
|
145
|
+
{String(slotContext?.queue ?? '—')}
|
|
146
|
+
</Text>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</ThemeProvider>
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export default App;
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@weavix/cli",
|
|
3
|
+
"version": "0.1.0-dev",
|
|
4
|
+
"description": "CLI to work with plugins of Yandex Tracker",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"bin": {
|
|
7
|
+
"weavix": "build/index.js"
|
|
8
|
+
},
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=22.0.0"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@aws-sdk/client-s3": "3.972.0",
|
|
14
|
+
"@aws-sdk/lib-storage": "3.972.0",
|
|
15
|
+
"@inquirer/prompts": "8.2.0",
|
|
16
|
+
"@types/archiver": "7.0.0",
|
|
17
|
+
"ajv": "8.17.1",
|
|
18
|
+
"ajv-formats": "3.0.1",
|
|
19
|
+
"archiver": "7.0.1",
|
|
20
|
+
"commander": "14.0.3",
|
|
21
|
+
"execa": "9.6.1",
|
|
22
|
+
"form-data": "4.0.5",
|
|
23
|
+
"node-fetch": "3.3.2",
|
|
24
|
+
"picocolors": "1.1.1",
|
|
25
|
+
"tinyglobby": "0.2.15"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"build",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"registry": "https://registry.npmjs.org",
|
|
33
|
+
"access": "public"
|
|
34
|
+
}
|
|
35
|
+
}
|