@teambit/component 0.0.1078 → 0.0.1080
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/component.ui.runtime.tsx +19 -9
- package/dist/component.d.ts +1 -1
- package/dist/component.graphql.d.ts +5 -2
- package/dist/component.graphql.js +4 -1
- package/dist/component.graphql.js.map +1 -1
- package/dist/component.ui.runtime.js +17 -9
- package/dist/component.ui.runtime.js.map +1 -1
- package/dist/get-component-opts.d.ts +1 -2
- package/dist/get-component-opts.js.map +1 -1
- package/dist/{preview-1686799133952.js → preview-1686971843539.js} +2 -2
- package/dist/ui/component.d.ts +1 -2
- package/dist/ui/component.js +24 -9
- package/dist/ui/component.js.map +1 -1
- package/dist/ui/index.d.ts +5 -2
- package/dist/ui/index.js +59 -9
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/menu/index.d.ts +1 -1
- package/dist/ui/menu/index.js.map +1 -1
- package/dist/ui/menu/menu.d.ts +47 -8
- package/dist/ui/menu/menu.js +172 -84
- package/dist/ui/menu/menu.js.map +1 -1
- package/dist/ui/menu/nav-plugin.d.ts +12 -3
- package/dist/ui/menu/nav-plugin.js.map +1 -1
- package/dist/ui/use-component-logs.d.ts +16 -0
- package/dist/ui/use-component-logs.js +93 -0
- package/dist/ui/use-component-logs.js.map +1 -0
- package/dist/ui/use-component-query.d.ts +2 -86
- package/dist/ui/use-component-query.js +62 -188
- package/dist/ui/use-component-query.js.map +1 -1
- package/dist/ui/use-component.d.ts +3 -18
- package/dist/ui/use-component.fragments.d.ts +10 -0
- package/dist/ui/use-component.fragments.js +183 -0
- package/dist/ui/use-component.fragments.js.map +1 -0
- package/dist/ui/use-component.js +19 -0
- package/dist/ui/use-component.js.map +1 -1
- package/dist/ui/use-component.model.d.ts +40 -0
- package/dist/ui/use-component.model.js +3 -0
- package/dist/ui/use-component.model.js.map +1 -0
- package/dist/ui/use-component.utils.d.ts +1 -0
- package/dist/ui/use-component.utils.js +17 -0
- package/dist/ui/use-component.utils.js.map +1 -0
- package/package-tar/teambit-component-0.0.1080.tgz +0 -0
- package/package.json +22 -23
- package/ui/component.tsx +11 -5
- package/ui/index.ts +21 -2
- package/ui/menu/index.ts +7 -1
- package/ui/menu/menu.tsx +196 -68
- package/ui/menu/nav-plugin.tsx +14 -6
- package/ui/use-component-logs.ts +65 -0
- package/ui/use-component-query.ts +57 -160
- package/ui/use-component.fragments.ts +169 -0
- package/ui/use-component.model.ts +45 -0
- package/ui/use-component.tsx +4 -19
- package/ui/use-component.utils.ts +9 -0
- package/package-tar/teambit-component-0.0.1078.tgz +0 -0
package/ui/menu/menu.tsx
CHANGED
|
@@ -1,25 +1,23 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
1
2
|
import { Routes, Route } from 'react-router-dom';
|
|
3
|
+
import classnames from 'classnames';
|
|
4
|
+
import { compact, flatten, groupBy, isFunction } from 'lodash';
|
|
5
|
+
import * as semver from 'semver';
|
|
6
|
+
import { DropdownComponentVersion, GetActiveTabIndex, VersionDropdown } from '@teambit/component.ui.version-dropdown';
|
|
2
7
|
import { MainDropdown, MenuItemSlot } from '@teambit/ui-foundation.ui.main-dropdown';
|
|
3
|
-
import { VersionDropdown } from '@teambit/component.ui.version-dropdown';
|
|
4
|
-
import { FullLoader } from '@teambit/ui-foundation.ui.full-loader';
|
|
5
8
|
import type { ConsumeMethod } from '@teambit/ui-foundation.ui.use-box.menu';
|
|
6
9
|
import { useLocation } from '@teambit/base-react.navigation.link';
|
|
7
|
-
import { flatten, groupBy, compact, isFunction } from 'lodash';
|
|
8
|
-
import classnames from 'classnames';
|
|
9
|
-
import React, { useMemo } from 'react';
|
|
10
10
|
import { UseBoxDropdown } from '@teambit/ui-foundation.ui.use-box.dropdown';
|
|
11
|
-
import { useLanes } from '@teambit/lanes.hooks.use-lanes';
|
|
12
|
-
import {
|
|
11
|
+
import { useLanes as defaultUseLanes } from '@teambit/lanes.hooks.use-lanes';
|
|
12
|
+
import { LanesModel } from '@teambit/lanes.ui.models.lanes-model';
|
|
13
13
|
import { Menu as ConsumeMethodsMenu } from '@teambit/ui-foundation.ui.use-box.menu';
|
|
14
14
|
import { LegacyComponentLog } from '@teambit/legacy-component-log';
|
|
15
|
-
import
|
|
16
|
-
import { useComponent as useComponentQuery, UseComponentType } from '../use-component';
|
|
15
|
+
import { useComponent as useComponentQuery, UseComponentType, Filters } from '../use-component';
|
|
17
16
|
import { CollapsibleMenuNav } from './menu-nav';
|
|
18
|
-
import
|
|
19
|
-
import { OrderedNavigationSlot, ConsumeMethodSlot } from './nav-plugin';
|
|
17
|
+
import { OrderedNavigationSlot, ConsumeMethodSlot, ConsumePluginProps } from './nav-plugin';
|
|
20
18
|
import { useIdFromLocation } from '../use-component-from-location';
|
|
21
19
|
import { ComponentID } from '../..';
|
|
22
|
-
import
|
|
20
|
+
import styles from './menu.module.scss';
|
|
23
21
|
|
|
24
22
|
export type MenuProps = {
|
|
25
23
|
className?: string;
|
|
@@ -54,9 +52,14 @@ export type MenuProps = {
|
|
|
54
52
|
|
|
55
53
|
useComponent?: UseComponentType;
|
|
56
54
|
|
|
57
|
-
path?: string;
|
|
58
|
-
|
|
59
55
|
useComponentFilters?: () => Filters;
|
|
56
|
+
|
|
57
|
+
useLanes?: () => {
|
|
58
|
+
loading?: boolean;
|
|
59
|
+
lanesModel?: LanesModel;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
path?: string;
|
|
60
63
|
};
|
|
61
64
|
function getComponentIdStr(componentIdStr?: string | (() => string | undefined)): string | undefined {
|
|
62
65
|
if (isFunction(componentIdStr)) return componentIdStr();
|
|
@@ -83,22 +86,27 @@ export function ComponentMenu({
|
|
|
83
86
|
const _componentIdStr = getComponentIdStr(componentIdStr);
|
|
84
87
|
const componentId = _componentIdStr ? ComponentID.fromString(_componentIdStr) : undefined;
|
|
85
88
|
const resolvedComponentIdStr = path || idFromLocation;
|
|
86
|
-
|
|
87
|
-
const useComponentOptions = {
|
|
88
|
-
logFilters: useComponentFilters?.(),
|
|
89
|
-
customUseComponent: useComponent,
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const { component } = useComponentQuery(host, componentId?.toString() || idFromLocation, useComponentOptions);
|
|
93
89
|
const mainMenuItems = useMemo(() => groupBy(flatten(menuItemSlot.values()), 'category'), [menuItemSlot]);
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
const componentFilters = useComponentFilters?.() || {};
|
|
91
|
+
const useComponentVersions = defaultLoadVersions(
|
|
92
|
+
host,
|
|
93
|
+
componentId?.toString() || idFromLocation,
|
|
94
|
+
componentFilters,
|
|
95
|
+
useComponent
|
|
96
|
+
);
|
|
96
97
|
|
|
97
98
|
const RightSide = (
|
|
98
99
|
<div className={styles.rightSide}>
|
|
99
100
|
{RightNode || (
|
|
100
101
|
<>
|
|
101
|
-
<VersionRelatedDropdowns
|
|
102
|
+
<VersionRelatedDropdowns
|
|
103
|
+
host={host}
|
|
104
|
+
consumeMethods={consumeMethodSlot}
|
|
105
|
+
componentId={componentId?.toString() || idFromLocation}
|
|
106
|
+
useComponent={useComponentVersions}
|
|
107
|
+
componentFilters={componentFilters}
|
|
108
|
+
// loading={loading}
|
|
109
|
+
/>
|
|
102
110
|
<MainDropdown className={styles.hideOnMobile} menuItems={mainMenuItems} />
|
|
103
111
|
</>
|
|
104
112
|
)}
|
|
@@ -122,91 +130,211 @@ export function ComponentMenu({
|
|
|
122
130
|
);
|
|
123
131
|
}
|
|
124
132
|
|
|
125
|
-
export
|
|
126
|
-
|
|
127
|
-
consumeMethods,
|
|
128
|
-
className,
|
|
129
|
-
host,
|
|
130
|
-
}: {
|
|
131
|
-
component: ComponentModel;
|
|
133
|
+
export type VersionRelatedDropdownsProps = {
|
|
134
|
+
componentId?: string;
|
|
132
135
|
consumeMethods?: ConsumeMethodSlot;
|
|
136
|
+
componentFilters?: Filters;
|
|
137
|
+
useComponent?: UseComponentVersions;
|
|
133
138
|
className?: string;
|
|
139
|
+
loading?: boolean;
|
|
134
140
|
host: string;
|
|
135
|
-
|
|
141
|
+
useLanes?: () => {
|
|
142
|
+
loading?: boolean;
|
|
143
|
+
lanesModel?: LanesModel;
|
|
144
|
+
};
|
|
145
|
+
dropdownOptions?: {
|
|
146
|
+
showVersionDetails?: boolean;
|
|
147
|
+
getActiveTabIndex?: GetActiveTabIndex;
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
export type UseComponentVersionsProps = {
|
|
151
|
+
skip?: boolean;
|
|
152
|
+
id?: string;
|
|
153
|
+
initialLoad?: boolean;
|
|
154
|
+
};
|
|
155
|
+
export type UseComponentVersionProps = {
|
|
156
|
+
skip?: boolean;
|
|
157
|
+
version?: string;
|
|
158
|
+
};
|
|
159
|
+
export type UseComponentVersions = (props?: UseComponentVersionsProps) => UseComponentVersionsResult;
|
|
160
|
+
export type UseComponentVersion = (props?: UseComponentVersionProps) => DropdownComponentVersion | undefined;
|
|
161
|
+
export type UseComponentVersionsResult = {
|
|
162
|
+
tags?: DropdownComponentVersion[];
|
|
163
|
+
snaps?: DropdownComponentVersion[];
|
|
164
|
+
id?: ComponentID;
|
|
165
|
+
packageName?: string;
|
|
166
|
+
latest?: string;
|
|
167
|
+
currentVersion?: string;
|
|
168
|
+
loading?: boolean;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export function defaultLoadVersions(
|
|
172
|
+
host: string,
|
|
173
|
+
componentId?: string,
|
|
174
|
+
componentFilters: Filters = {},
|
|
175
|
+
useComponent?: UseComponentType,
|
|
176
|
+
loadingFromProps?: boolean
|
|
177
|
+
): UseComponentVersions {
|
|
178
|
+
return React.useCallback(
|
|
179
|
+
(_props) => {
|
|
180
|
+
const { skip, initialLoad } = _props || {};
|
|
181
|
+
const fetchOptions = {
|
|
182
|
+
logFilters: {
|
|
183
|
+
...componentFilters,
|
|
184
|
+
log: {
|
|
185
|
+
...componentFilters.log,
|
|
186
|
+
limit: initialLoad ? 3 : undefined,
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
skip: loadingFromProps || skip,
|
|
190
|
+
customUseComponent: useComponent,
|
|
191
|
+
};
|
|
192
|
+
const {
|
|
193
|
+
component,
|
|
194
|
+
loading: loadingComponent,
|
|
195
|
+
componentLogs = {},
|
|
196
|
+
} = useComponentQuery(host, componentId, fetchOptions);
|
|
197
|
+
const logs = componentLogs?.logs;
|
|
198
|
+
const loading = React.useMemo(
|
|
199
|
+
() => loadingComponent || loadingFromProps || componentLogs.loading,
|
|
200
|
+
[loadingComponent, loadingFromProps, componentLogs.loading]
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
const snaps = useMemo(() => {
|
|
204
|
+
return (logs || []).filter((log) => !log.tag).map((snap) => ({ ...snap, version: snap.hash }));
|
|
205
|
+
}, [logs]);
|
|
206
|
+
|
|
207
|
+
const tags = useMemo(() => {
|
|
208
|
+
const tagLookup = new Map<string, LegacyComponentLog>();
|
|
209
|
+
(logs || [])
|
|
210
|
+
.filter((log) => log.tag)
|
|
211
|
+
.forEach((tag) => {
|
|
212
|
+
tagLookup.set(tag?.tag as string, tag);
|
|
213
|
+
});
|
|
214
|
+
return compact(
|
|
215
|
+
(component?.tags?.toArray() || []).reverse().map((tag) => tagLookup.get(tag.version.version))
|
|
216
|
+
).map((tag) => ({ ...tag, version: tag.tag as string }));
|
|
217
|
+
}, [logs]);
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
loading,
|
|
221
|
+
id: component?.id,
|
|
222
|
+
packageName: component?.packageName,
|
|
223
|
+
latestVersion: component?.latest,
|
|
224
|
+
currentVersion: component?.version,
|
|
225
|
+
snaps,
|
|
226
|
+
tags,
|
|
227
|
+
buildStatus: component?.buildStatus,
|
|
228
|
+
};
|
|
229
|
+
},
|
|
230
|
+
[componentId, loadingFromProps, componentFilters]
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export const defaultLoadCurrentVersion: (props: VersionRelatedDropdownsProps) => UseComponentVersion = (props) => {
|
|
235
|
+
return (_props) => {
|
|
236
|
+
const { skip, version: _version } = _props || {};
|
|
237
|
+
const { snaps, tags, currentVersion, loading } = props.useComponent?.({ skip, id: props.componentId }) ?? {};
|
|
238
|
+
const version = _version ?? currentVersion;
|
|
239
|
+
const isTag = React.useMemo(() => semver.valid(version), [loading, version]);
|
|
240
|
+
if (isTag) {
|
|
241
|
+
return React.useMemo(() => tags?.find((tag) => tag.tag === version), [loading, tags?.length, version]);
|
|
242
|
+
}
|
|
243
|
+
return React.useMemo(() => snaps?.find((snap) => snap.version === version), [loading, snaps?.length, version]);
|
|
244
|
+
};
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
export function VersionRelatedDropdowns(props: VersionRelatedDropdownsProps) {
|
|
248
|
+
const updatedPropsWithDefaults = {
|
|
249
|
+
...props,
|
|
250
|
+
useLanes: props.useLanes ?? defaultUseLanes,
|
|
251
|
+
dropdownOptions: {
|
|
252
|
+
...props.dropdownOptions,
|
|
253
|
+
showVersionDetails: props?.dropdownOptions?.showVersionDetails ?? true,
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const loadVersion = defaultLoadCurrentVersion(updatedPropsWithDefaults);
|
|
258
|
+
|
|
259
|
+
const { useLanes, consumeMethods, className, dropdownOptions, host } = updatedPropsWithDefaults;
|
|
260
|
+
const {
|
|
261
|
+
loading,
|
|
262
|
+
id,
|
|
263
|
+
tags,
|
|
264
|
+
snaps,
|
|
265
|
+
latest,
|
|
266
|
+
packageName,
|
|
267
|
+
currentVersion: _currentVersion,
|
|
268
|
+
} = props.useComponent?.({ initialLoad: true }) || {};
|
|
136
269
|
const location = useLocation();
|
|
137
270
|
const { lanesModel } = useLanes();
|
|
271
|
+
const lanes = id ? lanesModel?.getLanesByComponentId(id)?.filter((lane) => !lane.id.isDefault()) || [] : [];
|
|
138
272
|
const viewedLane =
|
|
139
273
|
lanesModel?.viewedLane?.id && !lanesModel?.viewedLane?.id.isDefault() ? lanesModel.viewedLane : undefined;
|
|
140
274
|
|
|
141
|
-
const { logs } = component;
|
|
142
275
|
const isWorkspace = host === 'teambit.workspace/workspace';
|
|
143
276
|
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
}, [logs]);
|
|
147
|
-
|
|
148
|
-
const tags = useMemo(() => {
|
|
149
|
-
const tagLookup = new Map<string, LegacyComponentLog>();
|
|
150
|
-
(logs || [])
|
|
151
|
-
.filter((log) => log.tag)
|
|
152
|
-
.forEach((tag) => {
|
|
153
|
-
tagLookup.set(tag?.tag as string, tag);
|
|
154
|
-
});
|
|
155
|
-
return compact(
|
|
156
|
-
component.tags
|
|
157
|
-
?.toArray()
|
|
158
|
-
.reverse()
|
|
159
|
-
.map((tag) => tagLookup.get(tag.version.version))
|
|
160
|
-
).map((tag) => ({ ...tag, version: tag.tag as string }));
|
|
161
|
-
}, [logs]);
|
|
162
|
-
|
|
163
|
-
const isNew = snaps.length === 0 && tags.length === 0;
|
|
164
|
-
|
|
165
|
-
const lanes = lanesModel?.getLanesByComponentId(component.id)?.filter((lane) => !lane.id.isDefault()) || [];
|
|
277
|
+
const isNew = tags?.length === 0 && snaps?.length === 0;
|
|
278
|
+
|
|
166
279
|
const localVersion = isWorkspace && !isNew && (!viewedLane || lanesModel?.isViewingCurrentLane());
|
|
167
280
|
|
|
168
281
|
const currentVersion =
|
|
169
|
-
isWorkspace && !isNew && !location?.search.includes('version') ? 'workspace' :
|
|
282
|
+
isWorkspace && !isNew && !location?.search.includes('version') ? 'workspace' : _currentVersion ?? '';
|
|
283
|
+
|
|
284
|
+
const consumeMethodProps: ConsumePluginProps | undefined = React.useMemo(() => {
|
|
285
|
+
return id
|
|
286
|
+
? {
|
|
287
|
+
id,
|
|
288
|
+
packageName: packageName ?? '',
|
|
289
|
+
latest,
|
|
290
|
+
options: { viewedLane, disableInstall: !packageName },
|
|
291
|
+
}
|
|
292
|
+
: undefined;
|
|
293
|
+
}, [id, packageName, latest, viewedLane]);
|
|
294
|
+
|
|
295
|
+
const methods = useConsumeMethods(consumeMethods, consumeMethodProps);
|
|
296
|
+
const hasMethods = methods?.length > 0;
|
|
170
297
|
|
|
171
|
-
const methods = useConsumeMethods(component, consumeMethods, viewedLane);
|
|
172
298
|
return (
|
|
173
299
|
<>
|
|
174
|
-
{consumeMethods &&
|
|
300
|
+
{consumeMethods && id && hasMethods && (
|
|
175
301
|
<UseBoxDropdown
|
|
176
302
|
position="bottom-end"
|
|
177
303
|
className={classnames(styles.useBox, styles.hideOnMobile)}
|
|
178
|
-
Menu={<ConsumeMethodsMenu methods={methods} componentName={
|
|
304
|
+
Menu={<ConsumeMethodsMenu methods={methods} componentName={id.name} />}
|
|
179
305
|
/>
|
|
180
306
|
)}
|
|
181
307
|
<VersionDropdown
|
|
182
|
-
tags={tags}
|
|
183
|
-
snaps={snaps}
|
|
184
308
|
lanes={lanes}
|
|
309
|
+
loading={loading}
|
|
310
|
+
useComponentVersions={props.useComponent}
|
|
311
|
+
hasMoreVersions={!isNew}
|
|
312
|
+
useCurrentVersionLog={loadVersion}
|
|
185
313
|
localVersion={localVersion}
|
|
186
314
|
currentVersion={currentVersion}
|
|
187
|
-
latestVersion={
|
|
315
|
+
latestVersion={latest}
|
|
188
316
|
currentLane={viewedLane}
|
|
189
317
|
className={className}
|
|
190
318
|
menuClassName={styles.componentVersionMenu}
|
|
319
|
+
getActiveTabIndex={dropdownOptions?.getActiveTabIndex}
|
|
320
|
+
showVersionDetails={dropdownOptions?.showVersionDetails}
|
|
191
321
|
/>
|
|
192
322
|
</>
|
|
193
323
|
);
|
|
194
324
|
}
|
|
195
325
|
|
|
196
326
|
function useConsumeMethods(
|
|
197
|
-
componentModel?: ComponentModel,
|
|
198
327
|
consumeMethods?: ConsumeMethodSlot,
|
|
199
|
-
|
|
328
|
+
consumePluginProps?: ConsumePluginProps
|
|
200
329
|
): ConsumeMethod[] {
|
|
201
|
-
// if (!consumeMethods || !componentModel) return [];
|
|
202
330
|
return useMemo(
|
|
203
331
|
() =>
|
|
204
332
|
flatten(consumeMethods?.values())
|
|
205
333
|
.map((method) => {
|
|
206
|
-
if (!
|
|
207
|
-
return method?.(
|
|
334
|
+
if (!consumePluginProps) return undefined;
|
|
335
|
+
return method?.(consumePluginProps);
|
|
208
336
|
})
|
|
209
337
|
.filter((x) => !!x && x.Component && x.Title) as ConsumeMethod[],
|
|
210
|
-
[consumeMethods,
|
|
338
|
+
[consumeMethods, consumePluginProps]
|
|
211
339
|
);
|
|
212
340
|
}
|
package/ui/menu/nav-plugin.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import { SlotRegistry } from '@teambit/harmony';
|
|
|
2
2
|
import type { LinkProps } from '@teambit/base-react.navigation.link';
|
|
3
3
|
import type { ConsumeMethod } from '@teambit/ui-foundation.ui.use-box.menu';
|
|
4
4
|
import { LaneModel } from '@teambit/lanes.ui.models.lanes-model';
|
|
5
|
-
import { ComponentModel } from '
|
|
5
|
+
import { ComponentID, ComponentModel } from '../..';
|
|
6
6
|
|
|
7
7
|
export type NavPluginProps = {
|
|
8
8
|
displayName?: string;
|
|
@@ -16,12 +16,20 @@ export type NavPlugin = {
|
|
|
16
16
|
|
|
17
17
|
export type OrderedNavigationSlot = SlotRegistry<NavPlugin>;
|
|
18
18
|
export type ConsumePluginOptions = {
|
|
19
|
-
|
|
19
|
+
viewedLane?: LaneModel;
|
|
20
|
+
hide?: boolean;
|
|
21
|
+
disableInstall?: boolean;
|
|
20
22
|
};
|
|
21
23
|
|
|
22
|
-
export type
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
export type ConsumePluginProps = {
|
|
25
|
+
id: ComponentID;
|
|
26
|
+
packageName: string;
|
|
27
|
+
latest?: string;
|
|
28
|
+
// @deprecated - pass id, packageName and latest instead via props
|
|
29
|
+
componentModel?: ComponentModel;
|
|
30
|
+
options?: ConsumePluginOptions;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type ConsumePlugin = (props: ConsumePluginProps) => ConsumeMethod | undefined;
|
|
26
34
|
|
|
27
35
|
export type ConsumeMethodSlot = SlotRegistry<ConsumePlugin[]>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { LegacyComponentLog } from '@teambit/legacy-component-log';
|
|
2
|
+
import { useDataQuery } from '@teambit/ui-foundation.ui.hooks.use-data-query';
|
|
3
|
+
import { ComponentLogsResult, Filters } from './use-component.model';
|
|
4
|
+
import { GET_COMPONENT_WITH_LOGS } from './use-component.fragments';
|
|
5
|
+
import { ComponentError } from './component-error';
|
|
6
|
+
import { getOffsetValue } from './use-component.utils';
|
|
7
|
+
|
|
8
|
+
export function useComponentLogs(
|
|
9
|
+
componentId: string,
|
|
10
|
+
host: string,
|
|
11
|
+
filters?: Filters,
|
|
12
|
+
skipFromProps?: boolean
|
|
13
|
+
): ComponentLogsResult {
|
|
14
|
+
const { variables, skip } = useComponentLogsInit(componentId, host, filters, skipFromProps);
|
|
15
|
+
|
|
16
|
+
const { data, error, loading } = useDataQuery(GET_COMPONENT_WITH_LOGS, {
|
|
17
|
+
variables,
|
|
18
|
+
skip,
|
|
19
|
+
errorPolicy: 'all',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const rawComponent = data?.getHost?.get;
|
|
23
|
+
const rawCompLogs: Array<LegacyComponentLog> = rawComponent?.logs;
|
|
24
|
+
|
|
25
|
+
const componentError =
|
|
26
|
+
error && !data
|
|
27
|
+
? new ComponentError(500, error.message)
|
|
28
|
+
: (!rawComponent && !loading && new ComponentError(404)) || undefined;
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
loading,
|
|
32
|
+
error: componentError,
|
|
33
|
+
componentLogs: {
|
|
34
|
+
logs: rawCompLogs,
|
|
35
|
+
loading,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function useComponentLogsInit(componentId: string, host: string, filters?: Filters, skip?: boolean) {
|
|
41
|
+
const { log } = filters || {};
|
|
42
|
+
const {
|
|
43
|
+
head: logHead,
|
|
44
|
+
offset: logOffset,
|
|
45
|
+
sort: logSort,
|
|
46
|
+
limit: logLimit,
|
|
47
|
+
type: logType,
|
|
48
|
+
takeHeadFromComponent: logTakeHeadFromComponent,
|
|
49
|
+
} = log || {};
|
|
50
|
+
const variables = {
|
|
51
|
+
id: componentId,
|
|
52
|
+
extensionId: host,
|
|
53
|
+
logOffset: getOffsetValue(logOffset, logLimit),
|
|
54
|
+
logLimit,
|
|
55
|
+
logType,
|
|
56
|
+
logHead,
|
|
57
|
+
logSort,
|
|
58
|
+
logTakeHeadFromComponent,
|
|
59
|
+
};
|
|
60
|
+
return {
|
|
61
|
+
logOffset,
|
|
62
|
+
variables,
|
|
63
|
+
skip,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -1,168 +1,42 @@
|
|
|
1
1
|
import { useMemo, useEffect, useRef } from 'react';
|
|
2
|
-
import { gql } from '@apollo/client';
|
|
3
2
|
import { useDataQuery } from '@teambit/ui-foundation.ui.hooks.use-data-query';
|
|
4
3
|
import { ComponentID, ComponentIdObj } from '@teambit/component-id';
|
|
5
4
|
import { ComponentDescriptor } from '@teambit/component-descriptor';
|
|
6
|
-
|
|
7
5
|
import { ComponentModel } from './component-model';
|
|
6
|
+
import { ComponentQueryResult, Filters } from './use-component.model';
|
|
7
|
+
import {
|
|
8
|
+
GET_COMPONENT,
|
|
9
|
+
SUB_COMPONENT_CHANGED,
|
|
10
|
+
SUB_COMPONENT_REMOVED,
|
|
11
|
+
SUB_SUBSCRIPTION_ADDED,
|
|
12
|
+
} from './use-component.fragments';
|
|
13
|
+
import { useComponentLogs } from './use-component-logs';
|
|
8
14
|
import { ComponentError } from './component-error';
|
|
9
15
|
|
|
10
|
-
export const componentIdFields = gql`
|
|
11
|
-
fragment componentIdFields on ComponentID {
|
|
12
|
-
name
|
|
13
|
-
version
|
|
14
|
-
scope
|
|
15
|
-
}
|
|
16
|
-
`;
|
|
17
|
-
|
|
18
|
-
export const componentOverviewFields = gql`
|
|
19
|
-
fragment componentOverviewFields on Component {
|
|
20
|
-
id {
|
|
21
|
-
...componentIdFields
|
|
22
|
-
}
|
|
23
|
-
aspects(include: ["teambit.preview/preview", "teambit.envs/envs"]) {
|
|
24
|
-
# 'id' property in gql refers to a *global* identifier and used for caching.
|
|
25
|
-
# this makes aspect data cache under the same key, even when they are under different components.
|
|
26
|
-
# renaming the property fixes that.
|
|
27
|
-
id
|
|
28
|
-
data
|
|
29
|
-
}
|
|
30
|
-
elementsUrl
|
|
31
|
-
description
|
|
32
|
-
deprecation {
|
|
33
|
-
isDeprecate
|
|
34
|
-
newId
|
|
35
|
-
}
|
|
36
|
-
labels
|
|
37
|
-
displayName
|
|
38
|
-
server {
|
|
39
|
-
env
|
|
40
|
-
url
|
|
41
|
-
host
|
|
42
|
-
basePath
|
|
43
|
-
}
|
|
44
|
-
buildStatus
|
|
45
|
-
env {
|
|
46
|
-
id
|
|
47
|
-
icon
|
|
48
|
-
}
|
|
49
|
-
size {
|
|
50
|
-
compressedTotal
|
|
51
|
-
}
|
|
52
|
-
preview {
|
|
53
|
-
includesEnvTemplate
|
|
54
|
-
legacyHeader
|
|
55
|
-
isScaling
|
|
56
|
-
skipIncludes
|
|
57
|
-
}
|
|
58
|
-
compositions {
|
|
59
|
-
identifier
|
|
60
|
-
displayName
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
${componentIdFields}
|
|
64
|
-
`;
|
|
65
|
-
|
|
66
|
-
export const componentFields = gql`
|
|
67
|
-
fragment componentFields on Component {
|
|
68
|
-
id {
|
|
69
|
-
...componentIdFields
|
|
70
|
-
}
|
|
71
|
-
...componentOverviewFields
|
|
72
|
-
packageName
|
|
73
|
-
latest
|
|
74
|
-
compositions {
|
|
75
|
-
identifier
|
|
76
|
-
displayName
|
|
77
|
-
}
|
|
78
|
-
tags {
|
|
79
|
-
version
|
|
80
|
-
}
|
|
81
|
-
logs(type: $logType, offset: $logOffset, limit: $logLimit, head: $logHead, sort: $logSort) {
|
|
82
|
-
id
|
|
83
|
-
message
|
|
84
|
-
username
|
|
85
|
-
email
|
|
86
|
-
date
|
|
87
|
-
hash
|
|
88
|
-
tag
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
${componentIdFields}
|
|
92
|
-
${componentOverviewFields}
|
|
93
|
-
`;
|
|
94
|
-
|
|
95
|
-
const GET_COMPONENT = gql`
|
|
96
|
-
query Component(
|
|
97
|
-
$id: String!
|
|
98
|
-
$extensionId: String!
|
|
99
|
-
$logType: String
|
|
100
|
-
$logOffset: Int
|
|
101
|
-
$logLimit: Int
|
|
102
|
-
$logHead: String
|
|
103
|
-
$logSort: String
|
|
104
|
-
) {
|
|
105
|
-
getHost(id: $extensionId) {
|
|
106
|
-
id # used for GQL caching
|
|
107
|
-
get(id: $id) {
|
|
108
|
-
...componentFields
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
${componentFields}
|
|
113
|
-
`;
|
|
114
|
-
|
|
115
|
-
const SUB_SUBSCRIPTION_ADDED = gql`
|
|
116
|
-
subscription OnComponentAdded($logType: String, $logOffset: Int, $logLimit: Int, $logHead: String, $logSort: String) {
|
|
117
|
-
componentAdded {
|
|
118
|
-
component {
|
|
119
|
-
...componentFields
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
${componentFields}
|
|
124
|
-
`;
|
|
125
|
-
|
|
126
|
-
const SUB_COMPONENT_CHANGED = gql`
|
|
127
|
-
subscription OnComponentChanged(
|
|
128
|
-
$logType: String
|
|
129
|
-
$logOffset: Int
|
|
130
|
-
$logLimit: Int
|
|
131
|
-
$logHead: String
|
|
132
|
-
$logSort: String
|
|
133
|
-
) {
|
|
134
|
-
componentChanged {
|
|
135
|
-
component {
|
|
136
|
-
...componentFields
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
${componentFields}
|
|
141
|
-
`;
|
|
142
|
-
|
|
143
|
-
const SUB_COMPONENT_REMOVED = gql`
|
|
144
|
-
subscription OnComponentRemoved {
|
|
145
|
-
componentRemoved {
|
|
146
|
-
componentIds {
|
|
147
|
-
...componentIdFields
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
${componentIdFields}
|
|
152
|
-
`;
|
|
153
|
-
export type Filters = {
|
|
154
|
-
log?: { logType?: string; logOffset?: number; logLimit?: number; logHead?: string; logSort?: string };
|
|
155
|
-
};
|
|
156
16
|
/** provides data to component ui page, making sure both variables and return value are safely typed and memoized */
|
|
157
|
-
export function useComponentQuery(
|
|
17
|
+
export function useComponentQuery(
|
|
18
|
+
componentId: string,
|
|
19
|
+
host: string,
|
|
20
|
+
filters?: Filters,
|
|
21
|
+
skip?: boolean
|
|
22
|
+
): ComponentQueryResult {
|
|
158
23
|
const idRef = useRef(componentId);
|
|
159
24
|
idRef.current = componentId;
|
|
160
|
-
const
|
|
161
|
-
|
|
25
|
+
const variables = {
|
|
26
|
+
id: componentId,
|
|
27
|
+
extensionId: host,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const { data, error, loading, subscribeToMore } = useDataQuery(GET_COMPONENT, {
|
|
31
|
+
variables,
|
|
162
32
|
skip,
|
|
163
33
|
errorPolicy: 'all',
|
|
164
34
|
});
|
|
165
35
|
|
|
36
|
+
const { loading: loadingLogs, componentLogs: { logs } = {} } = useComponentLogs(componentId, host, filters, skip);
|
|
37
|
+
|
|
38
|
+
const rawComponent = data?.getHost?.get;
|
|
39
|
+
|
|
166
40
|
useEffect(() => {
|
|
167
41
|
// @TODO @Kutner fix subscription for scope
|
|
168
42
|
if (host !== 'teambit.workspace/workspace') {
|
|
@@ -247,8 +121,26 @@ export function useComponentQuery(componentId: string, host: string, filters?: F
|
|
|
247
121
|
};
|
|
248
122
|
}, []);
|
|
249
123
|
|
|
250
|
-
const
|
|
251
|
-
|
|
124
|
+
const idDepKey = rawComponent?.id
|
|
125
|
+
? `${rawComponent?.id?.scope}/${rawComponent?.id?.name}@${rawComponent?.id?.version}}`
|
|
126
|
+
: undefined;
|
|
127
|
+
|
|
128
|
+
const id: ComponentID | undefined = useMemo(
|
|
129
|
+
() => (rawComponent ? ComponentID.fromObject(rawComponent.id) : undefined),
|
|
130
|
+
[idDepKey]
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const componentError =
|
|
134
|
+
error && !data
|
|
135
|
+
? new ComponentError(500, error.message)
|
|
136
|
+
: (!rawComponent && !loading && new ComponentError(404)) || undefined;
|
|
137
|
+
|
|
138
|
+
const component = useMemo(
|
|
139
|
+
() => (rawComponent ? ComponentModel.from({ ...rawComponent, host, logs }) : undefined),
|
|
140
|
+
[id?.toString(), logs]
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const componentDescriptor = useMemo(() => {
|
|
252
144
|
const aspectList = {
|
|
253
145
|
entries: rawComponent?.aspects.map((aspectObject) => {
|
|
254
146
|
return {
|
|
@@ -258,15 +150,20 @@ export function useComponentQuery(componentId: string, host: string, filters?: F
|
|
|
258
150
|
};
|
|
259
151
|
}),
|
|
260
152
|
};
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
153
|
+
|
|
154
|
+
return id ? ComponentDescriptor.fromObject({ id: id.toString(), aspectList }) : undefined;
|
|
155
|
+
}, [id?.toString()]);
|
|
156
|
+
|
|
157
|
+
return useMemo(() => {
|
|
264
158
|
return {
|
|
265
|
-
componentDescriptor
|
|
266
|
-
component
|
|
159
|
+
componentDescriptor,
|
|
160
|
+
component,
|
|
161
|
+
componentLogs: {
|
|
162
|
+
loading: loadingLogs,
|
|
163
|
+
logs,
|
|
164
|
+
},
|
|
267
165
|
error: componentError || undefined,
|
|
268
166
|
loading,
|
|
269
|
-
...rest,
|
|
270
167
|
};
|
|
271
|
-
}, [
|
|
168
|
+
}, [host, component, componentDescriptor, componentError]);
|
|
272
169
|
}
|