@teambit/workspace 0.0.568 → 0.0.569
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/__snapshots__/pick-outdated-pkgs.spec.ts.snap +88 -0
- package/component-config-file/component-config-file.ts +98 -0
- package/component-config-file/exceptions/already-exists.ts +7 -0
- package/component-config-file/exceptions/index.ts +1 -0
- package/component-config-file/index.ts +2 -0
- package/component-tree.widget.tsx +16 -0
- package/dist/__snapshots__/pick-outdated-pkgs.spec.js.snap +88 -0
- package/dist/__snapshots__/pick-outdated-pkgs.spec.ts.snap +88 -0
- package/dist/pick-outdated-pkgs.d.ts +12 -0
- package/dist/pick-outdated-pkgs.js +201 -0
- package/dist/pick-outdated-pkgs.js.map +1 -0
- package/dist/pick-outdated-pkgs.spec.d.ts +1 -0
- package/dist/pick-outdated-pkgs.spec.js +64 -0
- package/dist/pick-outdated-pkgs.spec.js.map +1 -0
- package/dist/update.cmd.js +3 -5
- package/dist/update.cmd.js.map +1 -1
- package/dist/workspace.d.ts +8 -1
- package/dist/workspace.js +28 -2
- package/dist/workspace.js.map +1 -1
- package/eject-conf.cmd.tsx +62 -0
- package/events/index.ts +3 -0
- package/events/on-component-add-event.ts +14 -0
- package/events/on-component-change-event.ts +14 -0
- package/events/on-component-removed-event.ts +14 -0
- package/exceptions/dependency-type-not-supported-in-policy.ts +7 -0
- package/exceptions/incorrect-env-aspect.ts +8 -0
- package/exceptions/index.ts +1 -0
- package/install.cmd.tsx +67 -0
- package/link/component-list-links.ts +50 -0
- package/link/core-aspects-links.ts +50 -0
- package/link/get-package-name-from-target.ts +5 -0
- package/link/index.ts +1 -0
- package/link/link-row.ts +20 -0
- package/link/link-to-dir.ts +13 -0
- package/link/link.cmd.ts +96 -0
- package/link/nested-deps-in-nm-links.ts +47 -0
- package/link/rewire-row.ts +17 -0
- package/list.cmd.tsx +30 -0
- package/package-tar/teambit-workspace-0.0.569.tgz +0 -0
- package/package.json +54 -65
- package/types/asset.d.ts +29 -0
- package/types/style.d.ts +42 -0
- package/ui/index.ts +1 -0
- package/ui/workspace/default-component.ts +7 -0
- package/ui/workspace/index.ts +1 -0
- package/ui/workspace/use-workspace.ts +193 -0
- package/ui/workspace/workspace-context.tsx +5 -0
- package/ui/workspace/workspace-model.ts +66 -0
- package/ui/workspace/workspace-overview/index.ts +1 -0
- package/ui/workspace/workspace-overview/workspace-overview.tsx +21 -0
- package/ui/workspace/workspace-provider.tsx +23 -0
- package/ui/workspace/workspace.tsx +99 -0
- package/ui/workspace-components-drawer/index.ts +1 -0
- package/ui/workspace-components-drawer/workspace-components.drawer.tsx +49 -0
- package/update.cmd.tsx +30 -0
- package/watch/check-types.ts +5 -0
- package/watch/output-formatter.ts +50 -0
- package/watch/watch.cmd.tsx +142 -0
- package/watch/watcher.ts +289 -0
- package/workspace-component/component-status.ts +67 -0
- package/workspace-component/index.ts +2 -0
- package/workspace-component/workspace-component-loader.ts +276 -0
- package/workspace-component/workspace-component.ts +51 -0
- package/workspace.ui.runtime.tsx +215 -0
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teambit/workspace",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.569",
|
|
4
4
|
"homepage": "https://bit.dev/teambit/workspace/workspace",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"componentId": {
|
|
7
7
|
"scope": "teambit.workspace",
|
|
8
8
|
"name": "workspace",
|
|
9
|
-
"version": "0.0.
|
|
9
|
+
"version": "0.0.569"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"lodash.compact": "3.0.1",
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
"p-map-series": "2.1.0",
|
|
15
15
|
"chalk": "2.4.2",
|
|
16
16
|
"ink": "3.0.8",
|
|
17
|
+
"@pnpm/colorize-semver-diff": "1.0.1",
|
|
18
|
+
"@pnpm/semver-diff": "1.1.0",
|
|
19
|
+
"enquirer": "2.3.6",
|
|
20
|
+
"table": "5.4.6",
|
|
17
21
|
"semver": "7.3.4",
|
|
18
22
|
"@teambit/harmony": "0.2.11",
|
|
19
23
|
"graphql-tag": "2.12.1",
|
|
@@ -34,55 +38,55 @@
|
|
|
34
38
|
"@teambit/base-ui.surfaces.split-pane.hover-splitter": "1.0.0",
|
|
35
39
|
"@teambit/base-ui.surfaces.split-pane.split-pane": "1.0.0",
|
|
36
40
|
"@teambit/base-ui.graph.tree.recursive-tree": "1.0.0",
|
|
37
|
-
"@teambit/bit-error": "0.0.
|
|
38
|
-
"@teambit/legacy-bit-id": "0.0.
|
|
39
|
-
"@teambit/logger": "0.0.
|
|
40
|
-
"@teambit/scope": "0.0.
|
|
41
|
-
"@teambit/cli": "0.0.
|
|
42
|
-
"@teambit/isolator": "0.0.
|
|
43
|
-
"@teambit/component-tree": "0.0.
|
|
44
|
-
"@teambit/component.ui.component-status-resolver": "0.0.
|
|
45
|
-
"@teambit/harmony.modules.resolved-component": "0.0.
|
|
46
|
-
"@teambit/dependency-resolver": "0.0.
|
|
47
|
-
"@teambit/compiler": "0.0.
|
|
48
|
-
"@teambit/component": "0.0.
|
|
49
|
-
"@teambit/graphql": "0.0.
|
|
50
|
-
"@teambit/aspect-loader": "0.0.
|
|
51
|
-
"@teambit/bundler": "0.0.
|
|
52
|
-
"@teambit/envs": "0.0.
|
|
53
|
-
"@teambit/pubsub": "0.0.
|
|
54
|
-
"@teambit/ui": "0.0.
|
|
55
|
-
"@teambit/variants": "0.0.
|
|
56
|
-
"@teambit/component-issues": "0.0.
|
|
57
|
-
"@teambit/config": "0.0.
|
|
58
|
-
"@teambit/harmony.modules.requireable-component": "0.0.
|
|
59
|
-
"@teambit/importer": "0.0.
|
|
60
|
-
"@teambit/workspace.modules.match-pattern": "0.0.
|
|
61
|
-
"@teambit/command-bar": "0.0.
|
|
41
|
+
"@teambit/bit-error": "0.0.381",
|
|
42
|
+
"@teambit/legacy-bit-id": "0.0.384",
|
|
43
|
+
"@teambit/logger": "0.0.481",
|
|
44
|
+
"@teambit/scope": "0.0.569",
|
|
45
|
+
"@teambit/cli": "0.0.395",
|
|
46
|
+
"@teambit/isolator": "0.0.569",
|
|
47
|
+
"@teambit/component-tree": "0.0.381",
|
|
48
|
+
"@teambit/component.ui.component-status-resolver": "0.0.476",
|
|
49
|
+
"@teambit/harmony.modules.resolved-component": "0.0.470",
|
|
50
|
+
"@teambit/dependency-resolver": "0.0.569",
|
|
51
|
+
"@teambit/compiler": "0.0.569",
|
|
52
|
+
"@teambit/component": "0.0.569",
|
|
53
|
+
"@teambit/graphql": "0.0.569",
|
|
54
|
+
"@teambit/aspect-loader": "0.0.569",
|
|
55
|
+
"@teambit/bundler": "0.0.569",
|
|
56
|
+
"@teambit/envs": "0.0.569",
|
|
57
|
+
"@teambit/pubsub": "0.0.569",
|
|
58
|
+
"@teambit/ui": "0.0.569",
|
|
59
|
+
"@teambit/variants": "0.0.483",
|
|
60
|
+
"@teambit/component-issues": "0.0.30",
|
|
61
|
+
"@teambit/config": "0.0.407",
|
|
62
|
+
"@teambit/harmony.modules.requireable-component": "0.0.470",
|
|
63
|
+
"@teambit/importer": "0.0.22",
|
|
64
|
+
"@teambit/workspace.modules.match-pattern": "0.0.474",
|
|
65
|
+
"@teambit/command-bar": "0.0.569",
|
|
62
66
|
"@teambit/design.ui.surfaces.menu.link-item": "0.0.374",
|
|
63
|
-
"@teambit/graph": "0.0.
|
|
64
|
-
"@teambit/react-router": "0.0.
|
|
65
|
-
"@teambit/sidebar": "0.0.
|
|
66
|
-
"@teambit/ui-foundation.ui.main-dropdown": "0.0.
|
|
67
|
-
"@teambit/ui-foundation.ui.menu": "0.0.
|
|
68
|
-
"@teambit/ui-foundation.ui.react-router.slot-router": "0.0.
|
|
69
|
-
"@teambit/toolbox.time.time-format": "0.0.
|
|
70
|
-
"@teambit/component-id": "0.0.
|
|
71
|
-
"@teambit/ui-foundation.ui.hooks.use-data-query": "0.0.
|
|
72
|
-
"@teambit/deprecation": "0.0.
|
|
73
|
-
"@teambit/ui-foundation.ui.constants.z-indexes": "0.0.
|
|
74
|
-
"@teambit/ui-foundation.ui.buttons.collapser": "0.0.
|
|
75
|
-
"@teambit/ui-foundation.ui.corner": "0.0.
|
|
76
|
-
"@teambit/ui-foundation.ui.notifications.notification-context": "0.0.
|
|
77
|
-
"@teambit/ui-foundation.ui.top-bar": "0.0.
|
|
67
|
+
"@teambit/graph": "0.0.569",
|
|
68
|
+
"@teambit/react-router": "0.0.569",
|
|
69
|
+
"@teambit/sidebar": "0.0.569",
|
|
70
|
+
"@teambit/ui-foundation.ui.main-dropdown": "0.0.472",
|
|
71
|
+
"@teambit/ui-foundation.ui.menu": "0.0.472",
|
|
72
|
+
"@teambit/ui-foundation.ui.react-router.slot-router": "0.0.474",
|
|
73
|
+
"@teambit/toolbox.time.time-format": "0.0.469",
|
|
74
|
+
"@teambit/component-id": "0.0.385",
|
|
75
|
+
"@teambit/ui-foundation.ui.hooks.use-data-query": "0.0.473",
|
|
76
|
+
"@teambit/deprecation": "0.0.569",
|
|
77
|
+
"@teambit/ui-foundation.ui.constants.z-indexes": "0.0.473",
|
|
78
|
+
"@teambit/ui-foundation.ui.buttons.collapser": "0.0.178",
|
|
79
|
+
"@teambit/ui-foundation.ui.corner": "0.0.479",
|
|
80
|
+
"@teambit/ui-foundation.ui.notifications.notification-context": "0.0.473",
|
|
81
|
+
"@teambit/ui-foundation.ui.top-bar": "0.0.475",
|
|
78
82
|
"@teambit/design.ui.styles.ellipsis": "0.0.346",
|
|
79
83
|
"@teambit/design.ui.styles.muted-italic": "0.0.35",
|
|
80
|
-
"@teambit/ui-foundation.ui.full-loader": "0.0.
|
|
81
|
-
"@teambit/ui-foundation.ui.side-bar": "0.0.
|
|
82
|
-
"@teambit/ui-foundation.ui.tree.drawer": "0.0.
|
|
83
|
-
"@teambit/explorer.ui.gallery.component-grid": "0.0.
|
|
84
|
-
"@teambit/workspace.ui.empty-workspace": "0.0.
|
|
85
|
-
"@teambit/workspace.ui.workspace-component-card": "0.0.
|
|
84
|
+
"@teambit/ui-foundation.ui.full-loader": "0.0.472",
|
|
85
|
+
"@teambit/ui-foundation.ui.side-bar": "0.0.478",
|
|
86
|
+
"@teambit/ui-foundation.ui.tree.drawer": "0.0.472",
|
|
87
|
+
"@teambit/explorer.ui.gallery.component-grid": "0.0.472",
|
|
88
|
+
"@teambit/workspace.ui.empty-workspace": "0.0.474",
|
|
89
|
+
"@teambit/workspace.ui.workspace-component-card": "0.0.476"
|
|
86
90
|
},
|
|
87
91
|
"devDependencies": {
|
|
88
92
|
"@types/lodash.compact": "3.0.6",
|
|
@@ -102,7 +106,7 @@
|
|
|
102
106
|
},
|
|
103
107
|
"peerDependencies": {
|
|
104
108
|
"@apollo/client": "^3.0.0",
|
|
105
|
-
"@teambit/legacy": "1.0.
|
|
109
|
+
"@teambit/legacy": "1.0.181",
|
|
106
110
|
"react-dom": "^16.8.0 || ^17.0.0",
|
|
107
111
|
"react": "^16.8.0 || ^17.0.0"
|
|
108
112
|
},
|
|
@@ -130,27 +134,12 @@
|
|
|
130
134
|
"react": "-"
|
|
131
135
|
},
|
|
132
136
|
"peerDependencies": {
|
|
133
|
-
"@teambit/legacy": "1.0.
|
|
137
|
+
"@teambit/legacy": "1.0.181",
|
|
134
138
|
"react-dom": "^16.8.0 || ^17.0.0",
|
|
135
139
|
"react": "^16.8.0 || ^17.0.0"
|
|
136
140
|
}
|
|
137
141
|
}
|
|
138
142
|
},
|
|
139
|
-
"files": [
|
|
140
|
-
"dist",
|
|
141
|
-
"!dist/tsconfig.tsbuildinfo",
|
|
142
|
-
"**/*.md",
|
|
143
|
-
"**/*.mdx",
|
|
144
|
-
"**/*.js",
|
|
145
|
-
"**/*.json",
|
|
146
|
-
"**/*.sass",
|
|
147
|
-
"**/*.scss",
|
|
148
|
-
"**/*.less",
|
|
149
|
-
"**/*.css",
|
|
150
|
-
"**/*.css",
|
|
151
|
-
"**/*.jpeg",
|
|
152
|
-
"**/*.gif"
|
|
153
|
-
],
|
|
154
143
|
"private": false,
|
|
155
144
|
"engines": {
|
|
156
145
|
"node": ">=12.22.0"
|
package/types/asset.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
declare module '*.png' {
|
|
2
|
+
const value: any;
|
|
3
|
+
export = value;
|
|
4
|
+
}
|
|
5
|
+
declare module '*.svg' {
|
|
6
|
+
import type { FunctionComponent, SVGProps } from 'react';
|
|
7
|
+
|
|
8
|
+
export const ReactComponent: FunctionComponent<SVGProps<SVGSVGElement> & { title?: string }>;
|
|
9
|
+
const src: string;
|
|
10
|
+
export default src;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// @TODO Gilad
|
|
14
|
+
declare module '*.jpg' {
|
|
15
|
+
const value: any;
|
|
16
|
+
export = value;
|
|
17
|
+
}
|
|
18
|
+
declare module '*.jpeg' {
|
|
19
|
+
const value: any;
|
|
20
|
+
export = value;
|
|
21
|
+
}
|
|
22
|
+
declare module '*.gif' {
|
|
23
|
+
const value: any;
|
|
24
|
+
export = value;
|
|
25
|
+
}
|
|
26
|
+
declare module '*.bmp' {
|
|
27
|
+
const value: any;
|
|
28
|
+
export = value;
|
|
29
|
+
}
|
package/types/style.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
declare module '*.module.css' {
|
|
2
|
+
const classes: { readonly [key: string]: string };
|
|
3
|
+
export default classes;
|
|
4
|
+
}
|
|
5
|
+
declare module '*.module.scss' {
|
|
6
|
+
const classes: { readonly [key: string]: string };
|
|
7
|
+
export default classes;
|
|
8
|
+
}
|
|
9
|
+
declare module '*.module.sass' {
|
|
10
|
+
const classes: { readonly [key: string]: string };
|
|
11
|
+
export default classes;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare module '*.module.less' {
|
|
15
|
+
const classes: { readonly [key: string]: string };
|
|
16
|
+
export default classes;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare module '*.less' {
|
|
20
|
+
const classes: { readonly [key: string]: string };
|
|
21
|
+
export default classes;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare module '*.css' {
|
|
25
|
+
const classes: { readonly [key: string]: string };
|
|
26
|
+
export default classes;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare module '*.sass' {
|
|
30
|
+
const classes: { readonly [key: string]: string };
|
|
31
|
+
export default classes;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
declare module '*.scss' {
|
|
35
|
+
const classes: { readonly [key: string]: string };
|
|
36
|
+
export default classes;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
declare module '*.mdx' {
|
|
40
|
+
const component: any;
|
|
41
|
+
export default component;
|
|
42
|
+
}
|
package/ui/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Workspace } from './workspace';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './workspace';
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { useEffect, useMemo } from 'react';
|
|
2
|
+
import { ComponentModel } from '@teambit/component';
|
|
3
|
+
import useLatest from '@react-hook/latest';
|
|
4
|
+
import { useDataQuery } from '@teambit/ui-foundation.ui.hooks.use-data-query';
|
|
5
|
+
import { gql } from '@apollo/client';
|
|
6
|
+
import { ComponentID, ComponentIdObj } from '@teambit/component-id';
|
|
7
|
+
|
|
8
|
+
import { Workspace } from './workspace-model';
|
|
9
|
+
|
|
10
|
+
type UseWorkspaceOptions = {
|
|
11
|
+
onComponentAdded?: (component: ComponentModel[]) => void;
|
|
12
|
+
onComponentUpdated?: (component: ComponentModel[]) => void;
|
|
13
|
+
onComponentRemoved?: (compId: ComponentID[]) => void;
|
|
14
|
+
};
|
|
15
|
+
type RawComponent = { id: ComponentIdObj };
|
|
16
|
+
|
|
17
|
+
const wcComponentFields = gql`
|
|
18
|
+
fragment wcComponentFields on Component {
|
|
19
|
+
id {
|
|
20
|
+
name
|
|
21
|
+
version
|
|
22
|
+
scope
|
|
23
|
+
}
|
|
24
|
+
compositions {
|
|
25
|
+
identifier
|
|
26
|
+
}
|
|
27
|
+
description
|
|
28
|
+
issuesCount
|
|
29
|
+
status {
|
|
30
|
+
isOutdated
|
|
31
|
+
isNew
|
|
32
|
+
isInScope
|
|
33
|
+
isStaged
|
|
34
|
+
modifyInfo {
|
|
35
|
+
hasModifiedFiles
|
|
36
|
+
hasModifiedDependencies
|
|
37
|
+
}
|
|
38
|
+
isDeleted
|
|
39
|
+
}
|
|
40
|
+
deprecation {
|
|
41
|
+
isDeprecate
|
|
42
|
+
}
|
|
43
|
+
server {
|
|
44
|
+
env
|
|
45
|
+
url
|
|
46
|
+
}
|
|
47
|
+
env {
|
|
48
|
+
id
|
|
49
|
+
icon
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
const WORKSPACE = gql`
|
|
55
|
+
query workspace {
|
|
56
|
+
workspace {
|
|
57
|
+
name
|
|
58
|
+
path
|
|
59
|
+
icon
|
|
60
|
+
components {
|
|
61
|
+
...wcComponentFields
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
${wcComponentFields}
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
const COMPONENT_SUBSCRIPTION_ADDED = gql`
|
|
69
|
+
subscription OnComponentAdded {
|
|
70
|
+
componentAdded {
|
|
71
|
+
component {
|
|
72
|
+
...wcComponentFields
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
${wcComponentFields}
|
|
77
|
+
`;
|
|
78
|
+
|
|
79
|
+
const COMPONENT_SUBSCRIPTION_CHANGED = gql`
|
|
80
|
+
subscription OnComponentChanged {
|
|
81
|
+
componentChanged {
|
|
82
|
+
component {
|
|
83
|
+
...wcComponentFields
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
${wcComponentFields}
|
|
88
|
+
`;
|
|
89
|
+
|
|
90
|
+
const COMPONENT_SUBSCRIPTION_REMOVED = gql`
|
|
91
|
+
subscription OnComponentRemoved {
|
|
92
|
+
componentRemoved {
|
|
93
|
+
componentIds {
|
|
94
|
+
name
|
|
95
|
+
version
|
|
96
|
+
scope
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
export function useWorkspace(options: UseWorkspaceOptions = {}) {
|
|
103
|
+
const { data, subscribeToMore, ...rest } = useDataQuery(WORKSPACE);
|
|
104
|
+
const optionsRef = useLatest(options);
|
|
105
|
+
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
const unSubCompAddition = subscribeToMore({
|
|
108
|
+
document: COMPONENT_SUBSCRIPTION_ADDED,
|
|
109
|
+
updateQuery: (prev, { subscriptionData }) => {
|
|
110
|
+
const update = subscriptionData.data;
|
|
111
|
+
const addedComponent = update?.componentAdded?.component;
|
|
112
|
+
if (!addedComponent) return prev;
|
|
113
|
+
|
|
114
|
+
const componentExists = prev.workspace.components.find((component: any) =>
|
|
115
|
+
ComponentID.isEqualObj(component.id, addedComponent.id, { ignoreVersion: true })
|
|
116
|
+
);
|
|
117
|
+
if (componentExists) return prev;
|
|
118
|
+
|
|
119
|
+
// side effect - trigger observers
|
|
120
|
+
setTimeout(() => optionsRef.current.onComponentAdded?.([ComponentModel.from(addedComponent)]));
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
...prev,
|
|
124
|
+
workspace: {
|
|
125
|
+
...prev.workspace,
|
|
126
|
+
components: [...prev.workspace.components, addedComponent],
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const unSubCompChange = subscribeToMore({
|
|
133
|
+
document: COMPONENT_SUBSCRIPTION_CHANGED,
|
|
134
|
+
updateQuery: (prev, { subscriptionData }) => {
|
|
135
|
+
const update = subscriptionData.data;
|
|
136
|
+
if (!update) return prev;
|
|
137
|
+
|
|
138
|
+
const updatedComponent = update.componentChanged.component;
|
|
139
|
+
// side effect - trigger observers
|
|
140
|
+
setTimeout(() => optionsRef.current.onComponentUpdated?.([ComponentModel.from(updatedComponent)]));
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
...prev,
|
|
144
|
+
workspace: {
|
|
145
|
+
...prev.workspace,
|
|
146
|
+
components: prev.workspace.components.map((component) =>
|
|
147
|
+
component.id.name === updatedComponent.id.name ? updatedComponent : component
|
|
148
|
+
),
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const unSubCompRemoved = subscribeToMore({
|
|
155
|
+
document: COMPONENT_SUBSCRIPTION_REMOVED,
|
|
156
|
+
updateQuery: (prev, { subscriptionData }) => {
|
|
157
|
+
const idsToRemove: ComponentIdObj[] | undefined = subscriptionData.data?.componentRemoved?.componentIds;
|
|
158
|
+
if (!idsToRemove || idsToRemove.length === 0) return prev;
|
|
159
|
+
|
|
160
|
+
// side effect - trigger observers
|
|
161
|
+
setTimeout(() => optionsRef.current.onComponentRemoved?.(idsToRemove.map((id) => ComponentID.fromObject(id))));
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
...prev,
|
|
165
|
+
workspace: {
|
|
166
|
+
...prev.workspace,
|
|
167
|
+
components: prev.workspace.components.filter((component: RawComponent) =>
|
|
168
|
+
idsToRemove.every((id) => !ComponentID.isEqualObj(id, component.id))
|
|
169
|
+
),
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// TODO - sub to component removal
|
|
176
|
+
|
|
177
|
+
return () => {
|
|
178
|
+
unSubCompAddition();
|
|
179
|
+
unSubCompChange();
|
|
180
|
+
unSubCompRemoved();
|
|
181
|
+
};
|
|
182
|
+
}, [optionsRef]);
|
|
183
|
+
|
|
184
|
+
const workspace = useMemo(() => {
|
|
185
|
+
return data?.workspace ? Workspace.from(data?.workspace) : undefined;
|
|
186
|
+
}, [data?.workspace]);
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
workspace,
|
|
190
|
+
subscribeToMore,
|
|
191
|
+
...rest,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// import { ComponentMeta } from '@teambit/component';
|
|
2
|
+
import { ComponentID, ComponentModel, ComponentModelProps } from '@teambit/component';
|
|
3
|
+
import { DeprecationInfo } from '@teambit/deprecation';
|
|
4
|
+
import { Descriptor } from '@teambit/envs';
|
|
5
|
+
|
|
6
|
+
import { ComponentStatus } from '../../workspace-component/component-status';
|
|
7
|
+
|
|
8
|
+
export type WorkspaceModelComponent = {
|
|
9
|
+
id: ComponentID;
|
|
10
|
+
status: ComponentStatus;
|
|
11
|
+
deprecation: DeprecationInfo;
|
|
12
|
+
env: Descriptor;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type WorkspaceProps = {
|
|
16
|
+
name: string;
|
|
17
|
+
path: string;
|
|
18
|
+
components: ComponentModelProps[];
|
|
19
|
+
icon: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export class Workspace {
|
|
23
|
+
constructor(
|
|
24
|
+
/**
|
|
25
|
+
* name of the workspace.
|
|
26
|
+
*/
|
|
27
|
+
readonly name: string,
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* absolute path of the workspace.
|
|
31
|
+
*/
|
|
32
|
+
readonly path: string,
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* icon of the workspace.
|
|
36
|
+
*/
|
|
37
|
+
readonly icon: string,
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* components container in the workspace.
|
|
41
|
+
*/
|
|
42
|
+
readonly components: ComponentModel[]
|
|
43
|
+
) {}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* return a component from the workspace.
|
|
47
|
+
*/
|
|
48
|
+
getComponent(id: ComponentID) {
|
|
49
|
+
return this.components.find((component) => component.id.fullName === id.fullName);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static from({ name, path, components, icon }: WorkspaceProps) {
|
|
53
|
+
return new Workspace(
|
|
54
|
+
name,
|
|
55
|
+
path,
|
|
56
|
+
icon,
|
|
57
|
+
components.map((value) => {
|
|
58
|
+
return ComponentModel.from(value);
|
|
59
|
+
})
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static empty() {
|
|
64
|
+
return new Workspace('', '', '', []);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { WorkspaceOverview } from './workspace-overview';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
import { ComponentGrid } from '@teambit/explorer.ui.gallery.component-grid';
|
|
3
|
+
import { EmptyWorkspace } from '@teambit/workspace.ui.empty-workspace';
|
|
4
|
+
import { WorkspaceComponentCard } from '@teambit/workspace.ui.workspace-component-card';
|
|
5
|
+
import { WorkspaceContext } from '../workspace-context';
|
|
6
|
+
import styles from './workspace-overview.module.scss';
|
|
7
|
+
|
|
8
|
+
export function WorkspaceOverview() {
|
|
9
|
+
const workspace = useContext(WorkspaceContext);
|
|
10
|
+
const { components } = workspace;
|
|
11
|
+
if (!components || components.length === 0) return <EmptyWorkspace name={workspace.name} />;
|
|
12
|
+
return (
|
|
13
|
+
<div className={styles.container}>
|
|
14
|
+
<ComponentGrid>
|
|
15
|
+
{components.map((component, index) => {
|
|
16
|
+
return <WorkspaceComponentCard key={index} component={component} />;
|
|
17
|
+
})}
|
|
18
|
+
</ComponentGrid>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
import { WorkspaceContext } from './workspace-context';
|
|
4
|
+
import { Workspace } from './workspace-model';
|
|
5
|
+
|
|
6
|
+
export type WorkspaceProviderProps = {
|
|
7
|
+
/**
|
|
8
|
+
* workspace model.
|
|
9
|
+
*/
|
|
10
|
+
workspace: Workspace;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* react children.
|
|
14
|
+
*/
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* context provider of the workspace
|
|
20
|
+
*/
|
|
21
|
+
export function WorkspaceProvider({ workspace, children }: WorkspaceProviderProps) {
|
|
22
|
+
return <WorkspaceContext.Provider value={workspace}>{children}</WorkspaceContext.Provider>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import 'reset-css';
|
|
2
|
+
import pluralize from 'pluralize';
|
|
3
|
+
import React, { useReducer, useMemo } from 'react';
|
|
4
|
+
import { Route } from 'react-router-dom';
|
|
5
|
+
import type { ComponentModel } from '@teambit/component';
|
|
6
|
+
import type { ComponentID } from '@teambit/component-id';
|
|
7
|
+
import { useNotifications } from '@teambit/ui-foundation.ui.notifications.notification-context';
|
|
8
|
+
import { RouteSlot, SlotRouter } from '@teambit/ui-foundation.ui.react-router.slot-router';
|
|
9
|
+
import { Corner } from '@teambit/ui-foundation.ui.corner';
|
|
10
|
+
import { Collapser } from '@teambit/ui-foundation.ui.buttons.collapser';
|
|
11
|
+
import { SplitPane, Pane, Layout } from '@teambit/base-ui.surfaces.split-pane.split-pane';
|
|
12
|
+
import { HoverSplitter } from '@teambit/base-ui.surfaces.split-pane.hover-splitter';
|
|
13
|
+
import { TopBar } from '@teambit/ui-foundation.ui.top-bar';
|
|
14
|
+
|
|
15
|
+
import { useWorkspace } from './use-workspace';
|
|
16
|
+
import { WorkspaceOverview } from './workspace-overview';
|
|
17
|
+
import { WorkspaceProvider } from './workspace-provider';
|
|
18
|
+
import styles from './workspace.module.scss';
|
|
19
|
+
import WorkspaceUI from '../../workspace.ui.runtime';
|
|
20
|
+
|
|
21
|
+
export type WorkspaceProps = {
|
|
22
|
+
routeSlot: RouteSlot;
|
|
23
|
+
menuSlot: RouteSlot;
|
|
24
|
+
sidebar: JSX.Element;
|
|
25
|
+
workspaceUI: WorkspaceUI;
|
|
26
|
+
onSidebarTogglerChange: (callback: () => void) => void;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* main workspace component.
|
|
31
|
+
*/
|
|
32
|
+
export function Workspace({ routeSlot, menuSlot, sidebar, workspaceUI, onSidebarTogglerChange }: WorkspaceProps) {
|
|
33
|
+
const reactions = useComponentNotifications();
|
|
34
|
+
const { workspace } = useWorkspace(reactions);
|
|
35
|
+
|
|
36
|
+
const [isSidebarOpen, handleSidebarToggle] = useReducer((x) => !x, true);
|
|
37
|
+
const sidebarOpenness = isSidebarOpen ? Layout.row : Layout.right;
|
|
38
|
+
|
|
39
|
+
onSidebarTogglerChange(handleSidebarToggle);
|
|
40
|
+
|
|
41
|
+
if (!workspace) {
|
|
42
|
+
return <div className={styles.emptyContainer}></div>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
workspaceUI.setComponents(workspace.components);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<WorkspaceProvider workspace={workspace}>
|
|
49
|
+
<div className={styles.workspaceWrapper}>
|
|
50
|
+
<TopBar
|
|
51
|
+
className={styles.topbar}
|
|
52
|
+
Corner={() => <Corner name={workspace.name} icon={workspace.icon} />}
|
|
53
|
+
menu={menuSlot}
|
|
54
|
+
/>
|
|
55
|
+
|
|
56
|
+
<SplitPane className={styles.main} size={264} layout={sidebarOpenness}>
|
|
57
|
+
<Pane className={styles.sidebar}>{sidebar}</Pane>
|
|
58
|
+
<HoverSplitter className={styles.splitter}>
|
|
59
|
+
<Collapser
|
|
60
|
+
isOpen={isSidebarOpen}
|
|
61
|
+
onMouseDown={(e) => e.stopPropagation()} // avoid split-pane drag
|
|
62
|
+
onClick={handleSidebarToggle}
|
|
63
|
+
tooltipContent={`${isSidebarOpen ? 'Hide' : 'Show'} side panel`}
|
|
64
|
+
/>
|
|
65
|
+
</HoverSplitter>
|
|
66
|
+
<Pane>
|
|
67
|
+
<SlotRouter slot={routeSlot} />
|
|
68
|
+
<Route exact path="/">
|
|
69
|
+
<WorkspaceOverview />
|
|
70
|
+
</Route>
|
|
71
|
+
</Pane>
|
|
72
|
+
</SplitPane>
|
|
73
|
+
</div>
|
|
74
|
+
</WorkspaceProvider>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
function useComponentNotifications() {
|
|
78
|
+
const notifications = useNotifications();
|
|
79
|
+
|
|
80
|
+
// memo not really needed, but for peace of mind
|
|
81
|
+
return useMemo(
|
|
82
|
+
() => ({
|
|
83
|
+
onComponentAdded: (comps: ComponentModel[]) => {
|
|
84
|
+
const notificationId = notifications.log(
|
|
85
|
+
`added ${pluralize('component', comps.length)}: ${comps.map((comp) => comp.id.toString()).join(', ')}`
|
|
86
|
+
);
|
|
87
|
+
setTimeout(() => notifications.dismiss(notificationId), 12 * 1000);
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
onComponentRemoved: (ids: ComponentID[]) => {
|
|
91
|
+
const notificationId = notifications.log(
|
|
92
|
+
`removed ${pluralize('component', ids.length)} ${ids.map((id) => id.toString()).join(', ')}`
|
|
93
|
+
);
|
|
94
|
+
setTimeout(() => notifications.dismiss(notificationId), 12 * 1000);
|
|
95
|
+
},
|
|
96
|
+
}),
|
|
97
|
+
[notifications]
|
|
98
|
+
);
|
|
99
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { WorkspaceComponentsDrawer } from './workspace-components.drawer';
|