@interopio/iocd-cli 1.0.3 → 1.1.1
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 +2 -839
- package/changelog.md +26 -0
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/apps.command.js +78 -0
- package/dist/commands/apps.command.js.map +1 -1
- package/dist/commands/index.js +3 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/modifications.command.js +2 -2
- package/dist/commands/modifications.command.js.map +1 -1
- package/dist/commands/skills.command.js +56 -0
- package/dist/commands/skills.command.js.map +1 -0
- package/dist/commands/test.command.js +6 -0
- package/dist/commands/test.command.js.map +1 -1
- package/dist/services/components/components.service.js +17 -3
- package/dist/services/components/components.service.js.map +1 -1
- package/dist/services/components/stores/github.store.js +30 -2
- package/dist/services/components/stores/github.store.js.map +1 -1
- package/dist/services/installer/electronForge.js +5 -0
- package/dist/services/installer/electronForge.js.map +1 -1
- package/dist/services/installer/installer.service.js +26 -0
- package/dist/services/installer/installer.service.js.map +1 -1
- package/dist/services/installer/prerequisites.js +10 -3
- package/dist/services/installer/prerequisites.js.map +1 -1
- package/dist/services/installer/windows.helper.js +17 -1
- package/dist/services/installer/windows.helper.js.map +1 -1
- package/dist/services/installer/zip-maker.js +122 -0
- package/dist/services/installer/zip-maker.js.map +1 -0
- package/dist/services/installer/zip.helper.js +94 -0
- package/dist/services/installer/zip.helper.js.map +1 -0
- package/dist/services/license.service.js +58 -8
- package/dist/services/license.service.js.map +1 -1
- package/dist/services/modifications/modifications.service.js +22 -1
- package/dist/services/modifications/modifications.service.js.map +1 -1
- package/dist/services/modifications/windows.helper.js +95 -49
- package/dist/services/modifications/windows.helper.js.map +1 -1
- package/dist/services/skills.service.js +178 -0
- package/dist/services/skills.service.js.map +1 -0
- package/dist/services/template.service.js +141 -9
- package/dist/services/template.service.js.map +1 -1
- package/dist/services/test-infrastructure.service.js +30 -17
- package/dist/services/test-infrastructure.service.js.map +1 -1
- package/dist/services/test.service.js +57 -21
- package/dist/services/test.service.js.map +1 -1
- package/dist/templates/ioconnect-desktop/README.md +2 -839
- package/dist/templates/ioconnect-desktop/config/forge.config.js +2 -2
- package/dist/templates/ioconnect-desktop/package.json +1 -2
- package/dist/templates/launchpad/apps/launchpad/.gitignore.template +23 -1
- package/dist/templates/launchpad/apps/launchpad/.prettierignore +3 -0
- package/dist/templates/launchpad/apps/launchpad/.prettierrc +6 -0
- package/dist/templates/launchpad/apps/launchpad/README.md +220 -0
- package/dist/templates/launchpad/apps/launchpad/config/iocd.app.def.dev.json +1 -1
- package/dist/templates/launchpad/apps/launchpad/index.html +13 -14
- package/dist/templates/launchpad/apps/launchpad/package.json +17 -9
- package/dist/templates/launchpad/apps/launchpad/src/app/app.tsx +31 -37
- package/dist/templates/launchpad/apps/launchpad/src/components/launchpad.tsx +37 -0
- package/dist/templates/launchpad/apps/launchpad/src/{app → constants}/constants.ts +2 -1
- package/dist/templates/launchpad/apps/launchpad/src/main.tsx +1 -3
- package/dist/templates/launchpad/apps/launchpad/src/styles.css +2 -17
- package/dist/templates/launchpad/apps/launchpad/tsconfig.json +10 -8
- package/dist/templates/launchpad/apps/launchpad/vite-env.d.ts +1 -0
- package/dist/templates/launchpad/apps/launchpad/vite.config.ts +8 -3
- package/dist/templates/tests/.agents/skills/iocd-wdio-testing/references/configuration.md +7 -3
- package/dist/templates/tests/tests/package.json +1 -1
- package/dist/utils/error.handler.js +6 -2
- package/dist/utils/error.handler.js.map +1 -1
- package/dist/utils/external-tool.js +34 -0
- package/dist/utils/external-tool.js.map +1 -0
- package/dist/utils/template-update.js +15 -0
- package/dist/utils/template-update.js.map +1 -0
- package/dist/utils/terminal-output-guard.js +5 -0
- package/dist/utils/terminal-output-guard.js.map +1 -0
- package/dist/utils/terminal-output.js +25 -0
- package/dist/utils/terminal-output.js.map +1 -0
- package/package.json +4 -1
- package/dist/templates/launchpad/apps/launchpad/package-lock.json +0 -2778
- package/dist/templates/launchpad/apps/launchpad/src/components/logo.tsx +0 -11
- package/dist/templates/launchpad/apps/launchpad/src/components/main-context-menu.tsx +0 -212
- package/dist/templates/launchpad/apps/launchpad/src/components/notifications-button.tsx +0 -51
- package/dist/templates/tests/tests/package-lock.json +0 -8441
|
@@ -10,7 +10,7 @@ module.exports = {
|
|
|
10
10
|
loadingGif: "assets/install.gif" // The local path to a .gif file to display during install.
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
|
-
{ name: '@
|
|
13
|
+
{ name: require.resolve('@interopio/iocd-cli/dist/services/installer/zip-maker') },
|
|
14
14
|
{ name: '@electron-forge/maker-dmg' },
|
|
15
15
|
],
|
|
16
16
|
publishers: [
|
|
@@ -44,4 +44,4 @@ module.exports = {
|
|
|
44
44
|
return packageJson;
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
|
-
};
|
|
47
|
+
};
|
|
@@ -27,9 +27,8 @@
|
|
|
27
27
|
"@electron-forge/core": "^7.9.0",
|
|
28
28
|
"@electron-forge/maker-dmg": "^7.9.0",
|
|
29
29
|
"@electron-forge/maker-squirrel": "^7.9.0",
|
|
30
|
-
"@electron-forge/maker-zip": "^7.9.0",
|
|
31
30
|
"@electron-forge/publisher-github": "^7.9.0",
|
|
32
31
|
"@electron-forge/publisher-electron-release-server": "^7.9.0",
|
|
33
32
|
"@electron-forge/publisher-s3": "^7.9.0"
|
|
34
33
|
}
|
|
35
|
-
}
|
|
34
|
+
}
|
|
@@ -1 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
|
2
|
+
|
|
3
|
+
# dependencies
|
|
4
|
+
/node_modules
|
|
5
|
+
/.pnp
|
|
6
|
+
.pnp.js
|
|
7
|
+
|
|
8
|
+
# testing
|
|
9
|
+
/coverage
|
|
10
|
+
|
|
11
|
+
# production
|
|
12
|
+
/build
|
|
13
|
+
|
|
14
|
+
# misc
|
|
15
|
+
.DS_Store
|
|
16
|
+
.env.local
|
|
17
|
+
.env.development.local
|
|
18
|
+
.env.test.local
|
|
19
|
+
.env.production.local
|
|
20
|
+
|
|
21
|
+
npm-debug.log*
|
|
22
|
+
yarn-debug.log*
|
|
23
|
+
yarn-error.log*
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Launchpad App for io.Connect Desktop
|
|
2
|
+
|
|
3
|
+
Template for creating a custom desktop Launchpad app for **io.Connect Desktop**, built on top of the
|
|
4
|
+
`IOLaunchpadDesktop` feature exported by [`@interopio/components-react`](https://www.npmjs.com/package/@interopio/components-react). Clone
|
|
5
|
+
this app and customize only the pieces you need — everything else keeps working out of the box.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
**io.Connect Desktop** is required, since this app only configures the `desktop` factory (see
|
|
10
|
+
[src/constants/constants.ts](src/constants/constants.ts)).
|
|
11
|
+
|
|
12
|
+
## Setup
|
|
13
|
+
|
|
14
|
+
- Run `npm install` to install all dependencies.
|
|
15
|
+
- Run `npm run start` to start the app (dev server runs on `http://localhost:4242` by default, see
|
|
16
|
+
[vite.config.ts](vite.config.ts)).
|
|
17
|
+
- Point your io.Connect Desktop configuration's Launchpad/System application entry to this app's URL, then start
|
|
18
|
+
io.Connect Desktop to see your customized Launchpad. Refer to your io.Connect Desktop version's documentation for
|
|
19
|
+
the exact application-definition file and property to update.
|
|
20
|
+
- Run `npm run build` to produce a production build in `dist/`.
|
|
21
|
+
- Start **io.Connect Desktop** to start using and modifying your Launchpad App.
|
|
22
|
+
|
|
23
|
+
## How it's wired
|
|
24
|
+
|
|
25
|
+
`src/components/launchpad.tsx` wires up the required providers around a single `<Launchpad />` component. You
|
|
26
|
+
don't need to pass a `components` prop at all - `<Launchpad />` already renders a fully working default header
|
|
27
|
+
(`DragHandle` + `LogoButton` before search, `ExtendedArea` + `NotificationsButton` + `MainContextMenu` after
|
|
28
|
+
search) out of the box:
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import {
|
|
32
|
+
ThemeProvider,
|
|
33
|
+
PlatformPrefsProvider,
|
|
34
|
+
IOActivePanelRenderer,
|
|
35
|
+
IODownloadManager,
|
|
36
|
+
IOLaunchpadDesktop,
|
|
37
|
+
IONotifications,
|
|
38
|
+
} from "@interopio/components-react";
|
|
39
|
+
|
|
40
|
+
const { LaunchpadProvider, LaunchpadBodyPopupProvider, PanelPopupProvider, Launchpad } = IOLaunchpadDesktop;
|
|
41
|
+
const { NotificationsProvider } = IONotifications;
|
|
42
|
+
const { DownloadManagerProvider } = IODownloadManager;
|
|
43
|
+
const { PanelManagerProvider } = IOActivePanelRenderer;
|
|
44
|
+
|
|
45
|
+
function LaunchpadWrapper() {
|
|
46
|
+
return (
|
|
47
|
+
<ThemeProvider>
|
|
48
|
+
<PlatformPrefsProvider>
|
|
49
|
+
<NotificationsProvider>
|
|
50
|
+
<DownloadManagerProvider>
|
|
51
|
+
<PanelManagerProvider>
|
|
52
|
+
<LaunchpadProvider>
|
|
53
|
+
<LaunchpadBodyPopupProvider>
|
|
54
|
+
<PanelPopupProvider>
|
|
55
|
+
<Launchpad />
|
|
56
|
+
</PanelPopupProvider>
|
|
57
|
+
</LaunchpadBodyPopupProvider>
|
|
58
|
+
</LaunchpadProvider>
|
|
59
|
+
</PanelManagerProvider>
|
|
60
|
+
</DownloadManagerProvider>
|
|
61
|
+
</NotificationsProvider>
|
|
62
|
+
</PlatformPrefsProvider>
|
|
63
|
+
</ThemeProvider>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
All customization happens through the `components` prop of `<Launchpad />` - you shouldn't need to touch the
|
|
69
|
+
provider chain above.
|
|
70
|
+
|
|
71
|
+
## Customization
|
|
72
|
+
|
|
73
|
+
### 1. Replacing the default io.Connect Desktop Launchpad with a custom implementation
|
|
74
|
+
|
|
75
|
+
For details on how io.Connect Desktop discovers and loads a custom Launchpad app, see the
|
|
76
|
+
[Launchpad documentation](https://docs.interop.io/desktop/capabilities/launcher/index.html#launchpad).
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
### 2. The `components` prop
|
|
80
|
+
|
|
81
|
+
`<Launchpad components={{ ... }} />` forwards straight to the native `IOLaunchpad.ContentsContainer`, so it only
|
|
82
|
+
accepts `header` (`BeforeSearch` / `AfterSearch`) and `sections` - there's no per-piece override system.
|
|
83
|
+
`DragHandle`, `LogoButton`, `NotificationsButton`, `MainContextMenu`, `ExtendedArea` are exported standalone so you
|
|
84
|
+
compose them yourself into `header.BeforeSearch` / `AfterSearch`, as shown above.
|
|
85
|
+
|
|
86
|
+
> **Tip:** define `BeforeSearch` / `AfterSearch` (and the `components` object) **outside** your component's render
|
|
87
|
+
> function (module scope), or memoize them. Passing a brand-new inline function on every render forces
|
|
88
|
+
> `<Launchpad />` to remount that zone on every render - wasteful in general, and it can also break in-flight
|
|
89
|
+
> async work started by a piece inside it (e.g. opening the docked search popup).
|
|
90
|
+
|
|
91
|
+
### 3. Default `BeforeSearch` / `AfterSearch`
|
|
92
|
+
|
|
93
|
+
`<Launchpad />` fills in `header.BeforeSearch` / `AfterSearch` with its own defaults whenever you don't specify
|
|
94
|
+
them, so there are 3 possible outcomes per zone:
|
|
95
|
+
|
|
96
|
+
1. **Omitted** (key not present, or `undefined`) - the library default renders (`DragHandle` + `LogoButton` for
|
|
97
|
+
`BeforeSearch`; `ExtendedArea` + `NotificationsButton` + `MainContextMenu` for `AfterSearch`).
|
|
98
|
+
2. **Explicitly empty** (e.g. `BeforeSearch: () => null`) - the default is overridden and nothing renders in that
|
|
99
|
+
zone.
|
|
100
|
+
3. **A real custom component** - that component renders in place of the default.
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
// 1. Omitted - renders the library defaults
|
|
104
|
+
<Launchpad />;
|
|
105
|
+
|
|
106
|
+
// 2. Explicitly empty - hides the zone entirely
|
|
107
|
+
<Launchpad components={{ header: { AfterSearch: () => null } }} />;
|
|
108
|
+
|
|
109
|
+
// 3. Custom component - fully replaces the zone
|
|
110
|
+
function CustomBeforeSearch() {
|
|
111
|
+
return <MyCustomLogo />;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
<Launchpad components={{ header: { BeforeSearch: CustomBeforeSearch } }} />;
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 4. Removing a piece
|
|
118
|
+
|
|
119
|
+
Since `header.BeforeSearch` / `AfterSearch` **fully replace** the zone, just omit a piece from your composition to
|
|
120
|
+
hide it - e.g. hide the notifications bell:
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
function AfterSearch() {
|
|
124
|
+
return (
|
|
125
|
+
<>
|
|
126
|
+
<ExtendedArea />
|
|
127
|
+
<MainContextMenu />
|
|
128
|
+
</>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 5. Passing your own component
|
|
134
|
+
|
|
135
|
+
Compose your own implementation alongside (or instead of) the default pieces:
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
function MyMainContextMenu() {
|
|
139
|
+
return <button onClick={() => console.log("clicked!")}>⋮</button>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function AfterSearch() {
|
|
143
|
+
return (
|
|
144
|
+
<>
|
|
145
|
+
<ExtendedArea />
|
|
146
|
+
<NotificationsButton />
|
|
147
|
+
<MyMainContextMenu />
|
|
148
|
+
</>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 6. Overriding `BeforeSearch` / `AfterSearch`
|
|
154
|
+
|
|
155
|
+
Pass `components.header` to fully replace either zone with something entirely custom:
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
function CustomBeforeSearch() {
|
|
159
|
+
return <MyCustomLogo />;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function CustomAfterSearch() {
|
|
163
|
+
return <MyCustomButton />;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const launchpadComponents = { header: { BeforeSearch: CustomBeforeSearch, AfterSearch: CustomAfterSearch } };
|
|
167
|
+
|
|
168
|
+
<Launchpad components={launchpadComponents} />;
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Since `header.BeforeSearch` / `AfterSearch` **fully replace** the zone, if you just want to add something
|
|
172
|
+
alongside the defaults, import the default pieces (they're also exported standalone) and compose them yourself:
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
import { IOLaunchpadDesktop } from "@interopio/components-react";
|
|
176
|
+
|
|
177
|
+
const { DragHandle, LogoButton } = IOLaunchpadDesktop;
|
|
178
|
+
|
|
179
|
+
function CustomBeforeSearch() {
|
|
180
|
+
return (
|
|
181
|
+
<>
|
|
182
|
+
<DragHandle />
|
|
183
|
+
<LogoButton />
|
|
184
|
+
<MyExtraBadge />
|
|
185
|
+
</>
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const launchpadComponents = { header: { BeforeSearch: CustomBeforeSearch } };
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 7. Customizing the `LogoButton`
|
|
193
|
+
|
|
194
|
+
`LogoButton` itself accepts `icon`, `iconSrc`, and `onClick` props, so you don't need to replace it entirely just
|
|
195
|
+
to change the logo or its click behavior:
|
|
196
|
+
|
|
197
|
+
```tsx
|
|
198
|
+
import { IOLaunchpadDesktop } from "@interopio/components-react";
|
|
199
|
+
|
|
200
|
+
const { DragHandle, LogoButton } = IOLaunchpadDesktop;
|
|
201
|
+
|
|
202
|
+
function BeforeSearch() {
|
|
203
|
+
return (
|
|
204
|
+
<>
|
|
205
|
+
<DragHandle />
|
|
206
|
+
<LogoButton iconSrc="/my-logo.png" onClick={() => console.log("logo clicked")} />
|
|
207
|
+
</>
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
- `icon` — an icon variant name (ignored if `iconSrc` is set); defaults to `"logo"`.
|
|
213
|
+
- `iconSrc` — a custom image URL/data-URI to render instead of `icon`.
|
|
214
|
+
- `onClick` — replaces the default collapse/popup-toggle behavior; drag-to-move still works either way.
|
|
215
|
+
|
|
216
|
+
### 7. `ExtendedArea` visibility
|
|
217
|
+
|
|
218
|
+
`ExtendedArea` self-guards: it renders `null` unless the Launchpad is both docked and the
|
|
219
|
+
`LAUNCHPAD_SHOW_EXTENDED_AREA` platform pref is enabled, so it's safe to always include it in `AfterSearch` - it
|
|
220
|
+
simply won't render anything otherwise.
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
<!
|
|
1
|
+
<!doctype html>
|
|
2
2
|
<html lang="en" class="dark">
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
</body>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>Launchpad</title>
|
|
6
|
+
<base href="./" />
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
8
|
+
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
|
9
|
+
<link rel="stylesheet" href="/src/styles.css" />
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="root"></div>
|
|
13
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
14
|
+
</body>
|
|
16
15
|
</html>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "
|
|
3
|
-
"version": "
|
|
2
|
+
"name": "io-connect-desktop-launchpad",
|
|
3
|
+
"version": "4.6.0",
|
|
4
4
|
"homepage": "./",
|
|
5
5
|
"private": true,
|
|
6
6
|
"scripts": {
|
|
@@ -8,14 +8,22 @@
|
|
|
8
8
|
"build": "vite build"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@interopio/components-react": "
|
|
12
|
-
"@interopio/
|
|
13
|
-
"@interopio/react-hooks": "
|
|
14
|
-
"@interopio/workspaces-ui-react": "
|
|
11
|
+
"@interopio/components-react": "~4.6.0",
|
|
12
|
+
"@interopio/desktop": "~6.16.0",
|
|
13
|
+
"@interopio/react-hooks": "~4.6.0",
|
|
14
|
+
"@interopio/workspaces-ui-react": "~4.6.0",
|
|
15
|
+
"@interopio/modals-api": "~4.6.0",
|
|
16
|
+
"@interopio/search-api": "^3.3.0",
|
|
17
|
+
"@interopio/theme": "~4.6.0",
|
|
18
|
+
"react": "~18.2.0",
|
|
19
|
+
"react-dom": "~18.2.0"
|
|
15
20
|
},
|
|
16
21
|
"devDependencies": {
|
|
17
|
-
"@
|
|
18
|
-
"
|
|
19
|
-
"
|
|
22
|
+
"@types/node": "~20.12.7",
|
|
23
|
+
"@types/react": "~18.2.79",
|
|
24
|
+
"@types/react-dom": "~18.2.25",
|
|
25
|
+
"@vitejs/plugin-react": "~3.0.0",
|
|
26
|
+
"typescript": "~5.8.2",
|
|
27
|
+
"vite": "~4.0.1"
|
|
20
28
|
}
|
|
21
29
|
}
|
|
@@ -1,45 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
LaunchpadHeader,
|
|
5
|
-
LaunchpadContentsContainer,
|
|
6
|
-
PlatformPrefsProvider,
|
|
7
|
-
} from "@interopio/home-ui-react";
|
|
8
|
-
import { ioConfig } from "./constants";
|
|
9
|
-
import { ThemeProvider, IONotifications } from "@interopio/components-react";
|
|
10
|
-
import Logo from "../components/logo";
|
|
11
|
-
import NotificationsButton from "../components/notifications-button";
|
|
12
|
-
import MainContextMenu from "../components/main-context-menu";
|
|
1
|
+
import { lazy, Suspense, useContext, useEffect } from "react";
|
|
2
|
+
import { IOConnectContext, IOConnectProvider } from "@interopio/react-hooks";
|
|
3
|
+
import { ioConfig } from "../constants/constants";
|
|
13
4
|
import "@interopio/workspaces-ui-react/dist/styles/workspaces.css";
|
|
14
|
-
import "@interopio/
|
|
5
|
+
import "@interopio/components-react/dist/styles/components/ui/dropdown-menu.css";
|
|
6
|
+
import "@interopio/components-react/dist/styles/components/ui/overlay-scrollbars-container.css";
|
|
7
|
+
import "@interopio/components-react/dist/styles/features/active-panel-renderer/styles.css";
|
|
8
|
+
import "@interopio/components-react/dist/styles/features/notifications/styles.css";
|
|
9
|
+
import "@interopio/components-react/dist/styles/features/preferences/styles.css";
|
|
10
|
+
import "@interopio/components-react/dist/styles/features/profile/styles.css";
|
|
11
|
+
import "@interopio/components-react/dist/styles/features/launchpad/styles.css";
|
|
12
|
+
import "@interopio/components-react/dist/styles/features/launchpad-desktop/styles.css";
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const Launchpad = lazy(() => import("../components/launchpad"));
|
|
15
|
+
|
|
16
|
+
// IOConnectProvider owns the only io.Connect initialization - read the resulting instance from context instead of initializing again.
|
|
17
|
+
function GlobalIOBinder() {
|
|
18
|
+
const io = useContext(IOConnectContext);
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (io) {
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
|
+
(globalThis as any).io = io;
|
|
24
|
+
}
|
|
25
|
+
}, [io]);
|
|
18
26
|
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function App() {
|
|
19
31
|
return (
|
|
20
32
|
<IOConnectProvider settings={ioConfig}>
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
components={{
|
|
26
|
-
header: {
|
|
27
|
-
BeforeSearch: () => <Logo />,
|
|
28
|
-
AfterSearch: () => (
|
|
29
|
-
<>
|
|
30
|
-
<NotificationsButton />
|
|
31
|
-
<MainContextMenu />
|
|
32
|
-
</>
|
|
33
|
-
),
|
|
34
|
-
},
|
|
35
|
-
}}
|
|
36
|
-
>
|
|
37
|
-
<LaunchpadHeader />
|
|
38
|
-
<LaunchpadBody />
|
|
39
|
-
</LaunchpadContentsContainer>
|
|
40
|
-
</NotificationsProvider>
|
|
41
|
-
</ThemeProvider>
|
|
42
|
-
</PlatformPrefsProvider>
|
|
33
|
+
<GlobalIOBinder />
|
|
34
|
+
<Suspense fallback={null}>
|
|
35
|
+
<Launchpad />
|
|
36
|
+
</Suspense>
|
|
43
37
|
</IOConnectProvider>
|
|
44
38
|
);
|
|
45
39
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ThemeProvider,
|
|
3
|
+
PlatformPrefsProvider,
|
|
4
|
+
IOActivePanelRenderer,
|
|
5
|
+
IODownloadManager,
|
|
6
|
+
IOLaunchpadDesktop,
|
|
7
|
+
IONotifications,
|
|
8
|
+
} from "@interopio/components-react";
|
|
9
|
+
|
|
10
|
+
const { PanelManagerProvider } = IOActivePanelRenderer;
|
|
11
|
+
const { DownloadManagerProvider } = IODownloadManager;
|
|
12
|
+
const { LaunchpadProvider, LaunchpadBodyPopupProvider, PanelPopupProvider, Launchpad } = IOLaunchpadDesktop;
|
|
13
|
+
const { NotificationsProvider } = IONotifications;
|
|
14
|
+
|
|
15
|
+
function LaunchpadWrapper() {
|
|
16
|
+
return (
|
|
17
|
+
<ThemeProvider>
|
|
18
|
+
<PlatformPrefsProvider>
|
|
19
|
+
<NotificationsProvider>
|
|
20
|
+
<DownloadManagerProvider>
|
|
21
|
+
<PanelManagerProvider>
|
|
22
|
+
<LaunchpadProvider>
|
|
23
|
+
<LaunchpadBodyPopupProvider>
|
|
24
|
+
<PanelPopupProvider>
|
|
25
|
+
<Launchpad />
|
|
26
|
+
</PanelPopupProvider>
|
|
27
|
+
</LaunchpadBodyPopupProvider>
|
|
28
|
+
</LaunchpadProvider>
|
|
29
|
+
</PanelManagerProvider>
|
|
30
|
+
</DownloadManagerProvider>
|
|
31
|
+
</NotificationsProvider>
|
|
32
|
+
</PlatformPrefsProvider>
|
|
33
|
+
</ThemeProvider>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default LaunchpadWrapper;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import IODesktop from "@interopio/desktop";
|
|
2
2
|
import IOSearch from "@interopio/search-api";
|
|
3
3
|
import IOWorkspaces from "@interopio/workspaces-api";
|
|
4
|
+
import IOModalsAPI from "@interopio/modals-api";
|
|
4
5
|
import { IOConnectInitSettings } from "@interopio/react-hooks";
|
|
5
6
|
|
|
6
7
|
export const ioConfig = {
|
|
@@ -12,7 +13,7 @@ export const ioConfig = {
|
|
|
12
13
|
level: "warn",
|
|
13
14
|
},
|
|
14
15
|
},
|
|
15
|
-
libraries: [IOWorkspaces, IOSearch],
|
|
16
|
+
libraries: [IOWorkspaces, IOSearch, IOModalsAPI],
|
|
16
17
|
appManager: "full",
|
|
17
18
|
layouts: "full",
|
|
18
19
|
activities: "trackAll",
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import * as ReactDOM from "react-dom/client";
|
|
2
2
|
import App from "./app/app";
|
|
3
3
|
|
|
4
|
-
const root = ReactDOM.createRoot(
|
|
5
|
-
document.getElementById("root") as HTMLElement
|
|
6
|
-
);
|
|
4
|
+
const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement);
|
|
7
5
|
|
|
8
6
|
root.render(<App />);
|
|
@@ -1,17 +1,2 @@
|
|
|
1
|
-
/*
|
|
2
|
-
|
|
3
|
-
position: relative;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
.launchpad-header-notifications-button .io-badge {
|
|
7
|
-
position: absolute;
|
|
8
|
-
top: 7px;
|
|
9
|
-
right: -2px;
|
|
10
|
-
display: flex;
|
|
11
|
-
align-items: center;
|
|
12
|
-
justify-content: center;
|
|
13
|
-
min-width: var(--spacing-16);
|
|
14
|
-
height: var(--spacing-16);
|
|
15
|
-
margin: calc(var(--spacing-10) * -1) auto 0 calc(var(--spacing-4) * -1);
|
|
16
|
-
font-size: var(--spacing-10);
|
|
17
|
-
}
|
|
1
|
+
/* App-specific overrides go here. Launchpad desktop styling now ships with
|
|
2
|
+
@interopio/components-react/dist/styles/features/launchpad-desktop/styles.css */
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "esnext",
|
|
4
|
+
"moduleResolution": "bundler",
|
|
5
|
+
"jsx": "react-jsx",
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"resolveJsonModule": true,
|
|
8
|
+
"allowJs": false,
|
|
9
|
+
"allowSyntheticDefaultImports": true,
|
|
10
|
+
"strict": true
|
|
11
|
+
}
|
|
10
12
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -2,10 +2,15 @@ import { defineConfig } from "vite";
|
|
|
2
2
|
import react from "@vitejs/plugin-react";
|
|
3
3
|
|
|
4
4
|
export default defineConfig({
|
|
5
|
+
plugins: [react()],
|
|
6
|
+
base: "./",
|
|
5
7
|
server: {
|
|
6
|
-
port:
|
|
8
|
+
port: 4242,
|
|
7
9
|
host: "localhost",
|
|
8
10
|
},
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
build: {
|
|
12
|
+
commonjsOptions: {
|
|
13
|
+
include: [/@interopio\/components-react/, /node_modules/],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
11
16
|
});
|
|
@@ -115,7 +115,7 @@ A seed configured with an interactive login (`ssoAuth` in the system config) rep
|
|
|
115
115
|
**after** someone signs in — without automation, `npm test` sits on the login window until the
|
|
116
116
|
startup timeout and no spec runs. The service's `login` option drives that window while the
|
|
117
117
|
platform boots. Requires `@interopio/wdio-iocd-service` 1.0.0-next.3+ (the version currently
|
|
118
|
-
generated)
|
|
118
|
+
generated) and io.Connect Desktop 10.4+; older test packages must update `tests/package.json` first.
|
|
119
119
|
|
|
120
120
|
```ts
|
|
121
121
|
// tests/wdio.config.ts
|
|
@@ -123,8 +123,12 @@ services: IOCDService({
|
|
|
123
123
|
login: {
|
|
124
124
|
window: { url: /login\.mycompany\.com/ }, // substring or RegExp; `title` also works
|
|
125
125
|
handler: async (browser) => {
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
const username = browser.$("#username");
|
|
127
|
+
const password = browser.$("#password");
|
|
128
|
+
await username.waitForExist({ timeout: 30000 });
|
|
129
|
+
await password.waitForExist({ timeout: 30000 });
|
|
130
|
+
await username.setValue(process.env.IOCD_TEST_USER!);
|
|
131
|
+
await password.setValue(process.env.IOCD_TEST_PASSWORD!);
|
|
128
132
|
await browser.$("button[type=submit]").click();
|
|
129
133
|
},
|
|
130
134
|
},
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@interopio/desktop": "^6.21.0",
|
|
13
|
-
"@interopio/wdio-iocd-service": "
|
|
13
|
+
"@interopio/wdio-iocd-service": "next",
|
|
14
14
|
"@interopio/workspaces-api": "^4.5.0",
|
|
15
15
|
"@types/chai": "^5.2.3",
|
|
16
16
|
"@types/mocha": "^10.0.10",
|
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.ErrorHandler = exports.CLIError = exports.ErrorCode = void 0;
|
|
36
|
+
exports.ErrorHandler = exports.shouldReportErrorToSentry = exports.CLIError = exports.ErrorCode = void 0;
|
|
37
37
|
const logger_1 = require("./logger");
|
|
38
38
|
const colors_1 = require("./colors");
|
|
39
39
|
const clack = __importStar(require("@clack/prompts"));
|
|
@@ -58,6 +58,7 @@ class CLIError extends Error {
|
|
|
58
58
|
cause;
|
|
59
59
|
suggestions;
|
|
60
60
|
showLogPath;
|
|
61
|
+
reportToSentry;
|
|
61
62
|
constructor(message, options = {}) {
|
|
62
63
|
super(message);
|
|
63
64
|
this.name = "CLIError";
|
|
@@ -65,9 +66,12 @@ class CLIError extends Error {
|
|
|
65
66
|
this.cause = options.cause;
|
|
66
67
|
this.suggestions = options.suggestions ?? [];
|
|
67
68
|
this.showLogPath = options.showLogPath ?? true;
|
|
69
|
+
this.reportToSentry = options.reportToSentry ?? true;
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
72
|
exports.CLIError = CLIError;
|
|
73
|
+
const shouldReportErrorToSentry = (error) => !(error instanceof CLIError) || error.reportToSentry;
|
|
74
|
+
exports.shouldReportErrorToSentry = shouldReportErrorToSentry;
|
|
71
75
|
class ErrorHandler {
|
|
72
76
|
static logger = logger_1.Logger.getInstance("error.handler");
|
|
73
77
|
static async handle(error) {
|
|
@@ -98,7 +102,7 @@ class ErrorHandler {
|
|
|
98
102
|
this.logger.flush();
|
|
99
103
|
// Give a small delay to ensure flush completes, then exit
|
|
100
104
|
await (0, delay_1.delay)(100);
|
|
101
|
-
if (config_service_1.ConfigManager.config.sentry) {
|
|
105
|
+
if (config_service_1.ConfigManager.config.sentry && (0, exports.shouldReportErrorToSentry)(error)) {
|
|
102
106
|
this.sendToSentry(error);
|
|
103
107
|
// Wait a bit to ensure Sentry sends the error before exiting
|
|
104
108
|
await (0, delay_1.delay)(100);
|