@sanity/dashboard 0.136.3-purple-unicorn-patch.5627

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.
Files changed (134) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +118 -0
  3. package/lib/cjs/DashboardTool.js +59 -0
  4. package/lib/cjs/components/DashboardLayout.js +35 -0
  5. package/lib/cjs/components/NotFoundWidget.js +53 -0
  6. package/lib/cjs/components/WidgetGroup.js +71 -0
  7. package/lib/cjs/components/dashboardWidget.js +55 -0
  8. package/lib/cjs/containers/Dashboard.js +32 -0
  9. package/lib/cjs/containers/WidgetContainer.js +52 -0
  10. package/lib/cjs/dashboardConfig.js +16 -0
  11. package/lib/cjs/legacyParts.js +55 -0
  12. package/lib/cjs/versionedClient.js +20 -0
  13. package/lib/cjs/widget.css +62 -0
  14. package/lib/cjs/widgets/projectInfo/ProjectInfo.js +269 -0
  15. package/lib/cjs/widgets/projectInfo/index.js +19 -0
  16. package/lib/cjs/widgets/projectUsers/ProjectUsers.js +194 -0
  17. package/lib/cjs/widgets/projectUsers/index.js +16 -0
  18. package/lib/cjs/widgets/sanityTutorials/SanityTutorials.js +122 -0
  19. package/lib/cjs/widgets/sanityTutorials/Tutorial.js +114 -0
  20. package/lib/cjs/widgets/sanityTutorials/dataAdapter.js +28 -0
  21. package/lib/cjs/widgets/sanityTutorials/index.js +19 -0
  22. package/lib/dts/src/DashboardTool.d.ts +11 -0
  23. package/lib/dts/src/DashboardTool.d.ts.map +1 -0
  24. package/lib/dts/src/DashboardTool.js +18 -0
  25. package/lib/dts/src/DashboardTool.js.map +1 -0
  26. package/lib/dts/src/components/DashboardLayout.d.ts +13 -0
  27. package/lib/dts/src/components/DashboardLayout.d.ts.map +1 -0
  28. package/lib/dts/src/components/DashboardLayout.js +15 -0
  29. package/lib/dts/src/components/DashboardLayout.js.map +1 -0
  30. package/lib/dts/src/components/NotFoundWidget.d.ts +16 -0
  31. package/lib/dts/src/components/NotFoundWidget.d.ts.map +1 -0
  32. package/lib/dts/src/components/NotFoundWidget.js +29 -0
  33. package/lib/dts/src/components/NotFoundWidget.js.map +1 -0
  34. package/lib/dts/src/components/WidgetGroup.d.ts +3 -0
  35. package/lib/dts/src/components/WidgetGroup.d.ts.map +1 -0
  36. package/lib/dts/src/components/WidgetGroup.js +81 -0
  37. package/lib/dts/src/components/WidgetGroup.js.map +1 -0
  38. package/lib/dts/src/components/dashboardWidget.d.ts +9 -0
  39. package/lib/dts/src/components/dashboardWidget.d.ts.map +1 -0
  40. package/lib/dts/src/components/dashboardWidget.js +48 -0
  41. package/lib/dts/src/components/dashboardWidget.js.map +1 -0
  42. package/lib/dts/src/containers/Dashboard.d.ts +3 -0
  43. package/lib/dts/src/containers/Dashboard.d.ts.map +1 -0
  44. package/lib/dts/src/containers/Dashboard.js +14 -0
  45. package/lib/dts/src/containers/Dashboard.js.map +1 -0
  46. package/lib/dts/src/containers/WidgetContainer.d.ts +13 -0
  47. package/lib/dts/src/containers/WidgetContainer.d.ts.map +1 -0
  48. package/lib/dts/src/containers/WidgetContainer.js +42 -0
  49. package/lib/dts/src/containers/WidgetContainer.js.map +1 -0
  50. package/lib/dts/src/dashboardConfig.d.ts +7 -0
  51. package/lib/dts/src/dashboardConfig.d.ts.map +1 -0
  52. package/lib/dts/src/dashboardConfig.js +4 -0
  53. package/lib/dts/src/dashboardConfig.js.map +1 -0
  54. package/lib/dts/src/legacyParts.d.ts +8 -0
  55. package/lib/dts/src/legacyParts.d.ts.map +1 -0
  56. package/lib/dts/src/legacyParts.js +10 -0
  57. package/lib/dts/src/legacyParts.js.map +1 -0
  58. package/lib/dts/src/versionedClient.d.ts +8 -0
  59. package/lib/dts/src/versionedClient.d.ts.map +1 -0
  60. package/lib/dts/src/versionedClient.js +9 -0
  61. package/lib/dts/src/versionedClient.js.map +1 -0
  62. package/lib/dts/src/widgets/projectInfo/ProjectInfo.d.ts +31 -0
  63. package/lib/dts/src/widgets/projectInfo/ProjectInfo.d.ts.map +1 -0
  64. package/lib/dts/src/widgets/projectInfo/ProjectInfo.js +155 -0
  65. package/lib/dts/src/widgets/projectInfo/ProjectInfo.js.map +1 -0
  66. package/lib/dts/src/widgets/projectInfo/index.d.ts +10 -0
  67. package/lib/dts/src/widgets/projectInfo/index.d.ts.map +1 -0
  68. package/lib/dts/src/widgets/projectInfo/index.js +7 -0
  69. package/lib/dts/src/widgets/projectInfo/index.js.map +1 -0
  70. package/lib/dts/src/widgets/projectUsers/ProjectUsers.d.ts +20 -0
  71. package/lib/dts/src/widgets/projectUsers/ProjectUsers.d.ts.map +1 -0
  72. package/lib/dts/src/widgets/projectUsers/ProjectUsers.js +108 -0
  73. package/lib/dts/src/widgets/projectUsers/ProjectUsers.js.map +1 -0
  74. package/lib/dts/src/widgets/projectUsers/index.d.ts +7 -0
  75. package/lib/dts/src/widgets/projectUsers/index.d.ts.map +1 -0
  76. package/lib/dts/src/widgets/projectUsers/index.js +6 -0
  77. package/lib/dts/src/widgets/projectUsers/index.js.map +1 -0
  78. package/lib/dts/src/widgets/sanityTutorials/SanityTutorials.d.ts +21 -0
  79. package/lib/dts/src/widgets/sanityTutorials/SanityTutorials.d.ts.map +1 -0
  80. package/lib/dts/src/widgets/sanityTutorials/SanityTutorials.js +61 -0
  81. package/lib/dts/src/widgets/sanityTutorials/SanityTutorials.js.map +1 -0
  82. package/lib/dts/src/widgets/sanityTutorials/Tutorial.d.ts +21 -0
  83. package/lib/dts/src/widgets/sanityTutorials/Tutorial.d.ts.map +1 -0
  84. package/lib/dts/src/widgets/sanityTutorials/Tutorial.js +84 -0
  85. package/lib/dts/src/widgets/sanityTutorials/Tutorial.js.map +1 -0
  86. package/lib/dts/src/widgets/sanityTutorials/dataAdapter.d.ts +6 -0
  87. package/lib/dts/src/widgets/sanityTutorials/dataAdapter.d.ts.map +1 -0
  88. package/lib/dts/src/widgets/sanityTutorials/dataAdapter.js +16 -0
  89. package/lib/dts/src/widgets/sanityTutorials/dataAdapter.js.map +1 -0
  90. package/lib/dts/src/widgets/sanityTutorials/index.d.ts +10 -0
  91. package/lib/dts/src/widgets/sanityTutorials/index.d.ts.map +1 -0
  92. package/lib/dts/src/widgets/sanityTutorials/index.js +7 -0
  93. package/lib/dts/src/widgets/sanityTutorials/index.js.map +1 -0
  94. package/lib/dts/tsconfig.tsbuildinfo +1 -0
  95. package/lib/esm/DashboardTool.js +33 -0
  96. package/lib/esm/components/DashboardLayout.js +23 -0
  97. package/lib/esm/components/NotFoundWidget.js +39 -0
  98. package/lib/esm/components/WidgetGroup.js +54 -0
  99. package/lib/esm/components/dashboardWidget.js +38 -0
  100. package/lib/esm/containers/Dashboard.js +19 -0
  101. package/lib/esm/containers/WidgetContainer.js +39 -0
  102. package/lib/esm/dashboardConfig.js +9 -0
  103. package/lib/esm/legacyParts.js +9 -0
  104. package/lib/esm/versionedClient.js +11 -0
  105. package/lib/esm/widget.css +62 -0
  106. package/lib/esm/widgets/projectInfo/ProjectInfo.js +254 -0
  107. package/lib/esm/widgets/projectInfo/index.js +8 -0
  108. package/lib/esm/widgets/projectUsers/ProjectUsers.js +174 -0
  109. package/lib/esm/widgets/projectUsers/index.js +5 -0
  110. package/lib/esm/widgets/sanityTutorials/SanityTutorials.js +108 -0
  111. package/lib/esm/widgets/sanityTutorials/Tutorial.js +98 -0
  112. package/lib/esm/widgets/sanityTutorials/dataAdapter.js +16 -0
  113. package/lib/esm/widgets/sanityTutorials/index.js +8 -0
  114. package/package.json +55 -0
  115. package/sanity.json +59 -0
  116. package/src/DashboardTool.js +32 -0
  117. package/src/components/DashboardLayout.js +22 -0
  118. package/src/components/NotFoundWidget.js +41 -0
  119. package/src/components/WidgetGroup.js +97 -0
  120. package/src/components/dashboardWidget.tsx +70 -0
  121. package/src/containers/Dashboard.js +20 -0
  122. package/src/containers/WidgetContainer.js +52 -0
  123. package/src/dashboardConfig.js +3 -0
  124. package/src/legacyParts.ts +11 -0
  125. package/src/versionedClient.js +9 -0
  126. package/src/widget.css +62 -0
  127. package/src/widgets/projectInfo/ProjectInfo.js +232 -0
  128. package/src/widgets/projectInfo/index.js +7 -0
  129. package/src/widgets/projectUsers/ProjectUsers.js +179 -0
  130. package/src/widgets/projectUsers/index.js +6 -0
  131. package/src/widgets/sanityTutorials/SanityTutorials.js +91 -0
  132. package/src/widgets/sanityTutorials/Tutorial.js +120 -0
  133. package/src/widgets/sanityTutorials/dataAdapter.js +17 -0
  134. package/src/widgets/sanityTutorials/index.js +7 -0
@@ -0,0 +1,179 @@
1
+ import React from 'react'
2
+ import {map, switchMap} from 'rxjs/operators'
3
+ import {Stack, Spinner, Card, Box, Text, Button} from '@sanity/ui'
4
+ import {RobotIcon} from '@sanity/icons'
5
+ import styled from 'styled-components'
6
+ import {DefaultPreview} from '@sanity/base'
7
+ import {versionedClient} from '../../versionedClient'
8
+ import {DashboardWidget} from '../../DashboardTool'
9
+ import {userStore} from '../../legacyParts'
10
+
11
+ const AvatarWrapper = styled(Card)`
12
+ box-sizing: border-box;
13
+ border-radius: 50%;
14
+ border-color: transparent;
15
+ overflow: hidden;
16
+ width: 100%;
17
+ height: 100%;
18
+
19
+ & > img {
20
+ width: 100%;
21
+ height: auto;
22
+ }
23
+ `
24
+
25
+ function getInviteUrl(projectId) {
26
+ return `https://manage.sanity.io/projects/${projectId}/team/invite`
27
+ }
28
+
29
+ function sortUsersByRobotStatus(userA, userB, project) {
30
+ const {members} = project
31
+ const membershipA = members.find((member) => member.id === userA.id)
32
+ const membershipB = members.find((member) => member.id === userB.id)
33
+ if (membershipA.isRobot) {
34
+ return 1
35
+ }
36
+ if (membershipB.isRobot) {
37
+ return -1
38
+ }
39
+ return 0
40
+ }
41
+
42
+ class ProjectUsers extends React.PureComponent {
43
+ static propTypes = {}
44
+ static defaultProps = {}
45
+
46
+ state = {
47
+ project: null,
48
+ users: null,
49
+ error: null,
50
+ }
51
+
52
+ componentDidMount() {
53
+ this.fetchData()
54
+ }
55
+
56
+ componentWillUnmount() {
57
+ if (this.subscription) {
58
+ this.subscription.unsubscribe()
59
+ }
60
+ }
61
+
62
+ fetchData() {
63
+ if (this.subscription) {
64
+ this.subscription.unsubscribe()
65
+ }
66
+
67
+ const {projectId} = versionedClient.config()
68
+ this.subscription = versionedClient.observable
69
+ .request({
70
+ uri: `/projects/${projectId}`,
71
+ })
72
+ .pipe(
73
+ switchMap((project) =>
74
+ userStore.observable
75
+ .getUsers(project.members.map((mem) => mem.id))
76
+ .pipe(map((users) => ({project, users})))
77
+ )
78
+ )
79
+ .subscribe({
80
+ next: ({users, project}) =>
81
+ this.setState({
82
+ project,
83
+ users: (Array.isArray(users) ? users : [users]).sort((userA, userB) =>
84
+ sortUsersByRobotStatus(userA, userB, project)
85
+ ),
86
+ }),
87
+ error: (error) => this.setState({error}),
88
+ })
89
+ }
90
+
91
+ handleRetryFetch = () => {
92
+ this.fetchData()
93
+ }
94
+
95
+ render() {
96
+ const {error, project, users} = this.state
97
+ const isLoading = !users || !project
98
+
99
+ if (error) {
100
+ return (
101
+ <DashboardWidget header="Project users">
102
+ <Box padding={4}>
103
+ <Text>
104
+ Something went wrong while fetching data. You could{' '}
105
+ <a
106
+ onClick={this.handleRetryFetch}
107
+ title="Retry users fetch"
108
+ style={{cursor: 'pointer'}}
109
+ >
110
+ retry
111
+ </a>
112
+ ..?
113
+ </Text>
114
+ </Box>
115
+ </DashboardWidget>
116
+ )
117
+ }
118
+
119
+ return (
120
+ <DashboardWidget
121
+ header="Project users"
122
+ footer={
123
+ <Button
124
+ style={{width: '100%'}}
125
+ paddingX={2}
126
+ paddingY={4}
127
+ mode="bleed"
128
+ tone="primary"
129
+ text="Invite members"
130
+ as="a"
131
+ loading={isLoading}
132
+ href={isLoading ? undefined : getInviteUrl(project.id)}
133
+ />
134
+ }
135
+ >
136
+ {isLoading && (
137
+ <Box paddingY={5} paddingX={2}>
138
+ <Stack space={4}>
139
+ <Text align="center" muted size={1}>
140
+ <Spinner />
141
+ </Text>
142
+ <Text align="center" size={1} muted>
143
+ Loading items...
144
+ </Text>
145
+ </Stack>
146
+ </Box>
147
+ )}
148
+
149
+ {!isLoading && (
150
+ <Stack space={3} padding={3}>
151
+ {users.map((user) => {
152
+ const membership = project.members.find((member) => member.id === user.id)
153
+ const media = membership.isRobot ? (
154
+ <Text size={3}>
155
+ <RobotIcon />
156
+ </Text>
157
+ ) : (
158
+ <AvatarWrapper tone="transparent">
159
+ {user?.imageUrl && <img src={user.imageUrl} alt={user?.displayName} />}
160
+ </AvatarWrapper>
161
+ )
162
+ return (
163
+ <Box key={user.id}>
164
+ <DefaultPreview
165
+ title={user.displayName}
166
+ subtitle={membership.role}
167
+ media={media}
168
+ />
169
+ </Box>
170
+ )
171
+ })}
172
+ </Stack>
173
+ )}
174
+ </DashboardWidget>
175
+ )
176
+ }
177
+ }
178
+
179
+ export default ProjectUsers
@@ -0,0 +1,6 @@
1
+ import ProjectUsers from './ProjectUsers'
2
+
3
+ export default {
4
+ name: 'project-users',
5
+ component: ProjectUsers,
6
+ }
@@ -0,0 +1,91 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import {get} from 'lodash'
4
+ import {Flex} from '@sanity/ui'
5
+ import {DashboardWidget} from '../../DashboardTool'
6
+ import Tutorial from './Tutorial'
7
+ import dataAdapter from './dataAdapter'
8
+
9
+ const {urlBuilder, getFeed} = dataAdapter
10
+
11
+ function createUrl(slug, type) {
12
+ if (type === 'tutorial') {
13
+ return `https://www.sanity.io/docs/tutorials/${slug.current}`
14
+ } else if (type === 'guide') {
15
+ return `https://www.sanity.io/docs/guides/${slug.current}`
16
+ }
17
+ return false
18
+ }
19
+
20
+ class SanityTutorials extends React.Component {
21
+ static propTypes = {
22
+ templateRepoId: PropTypes.string,
23
+ }
24
+
25
+ static defaultProps = {
26
+ templateRepoId: null,
27
+ }
28
+
29
+ state = {
30
+ feedItems: [],
31
+ }
32
+
33
+ componentDidMount() {
34
+ const {templateRepoId} = this.props
35
+ this.subscription = getFeed(templateRepoId).subscribe((response) => {
36
+ this.setState({
37
+ feedItems: response.items,
38
+ })
39
+ })
40
+ }
41
+
42
+ componentWillUnmount() {
43
+ if (this.subscription) {
44
+ this.subscription.unsubscribe()
45
+ }
46
+ }
47
+
48
+ render() {
49
+ const {feedItems} = this.state
50
+ const title = 'Learn about Sanity'
51
+
52
+ return (
53
+ <DashboardWidget header={title}>
54
+ <Flex as="ul" overflow="auto" align="stretch" paddingY={2}>
55
+ {feedItems?.map((feedItem, index) => {
56
+ if (!feedItem.title || (!feedItem.guideOrTutorial && !feedItem.externalLink)) {
57
+ return null
58
+ }
59
+ const presenter = feedItem.presenter || get(feedItem, 'guideOrTutorial.presenter') || {}
60
+ const subtitle = get(feedItem, 'category')
61
+ const {guideOrTutorial = {}} = feedItem
62
+ return (
63
+ <Flex
64
+ as="li"
65
+ key={feedItem._id}
66
+ paddingRight={index < feedItems?.length - 1 ? 1 : 3}
67
+ paddingLeft={index === 0 ? 3 : 0}
68
+ align="stretch"
69
+ flex="0 0 27.5%"
70
+ style={{minWidth: 272, width: '30%'}}
71
+ >
72
+ <Tutorial
73
+ title={feedItem.title}
74
+ href={
75
+ createUrl(guideOrTutorial.slug, guideOrTutorial._type) || feedItem.externalLink
76
+ }
77
+ presenterName={presenter.name}
78
+ presenterSubtitle={subtitle}
79
+ showPlayIcon={feedItem.hasVideo}
80
+ posterURL={urlBuilder.image(feedItem.poster).height(360).url()}
81
+ />
82
+ </Flex>
83
+ )
84
+ })}
85
+ </Flex>
86
+ </DashboardWidget>
87
+ )
88
+ }
89
+ }
90
+
91
+ export default SanityTutorials
@@ -0,0 +1,120 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import {Card, Box, Heading, Flex, Text, Stack} from '@sanity/ui'
4
+ import {PlayIcon} from '@sanity/icons'
5
+ import styled from 'styled-components'
6
+
7
+ const PlayIconBox = styled(Box)`
8
+ position: absolute;
9
+ top: 50%;
10
+ left: 50%;
11
+ transform: translate(-50%, -50%);
12
+
13
+ &:before {
14
+ content: '';
15
+ position: absolute;
16
+ top: 50%;
17
+ left: 50%;
18
+ transform: translate(-50%, -50%);
19
+ width: 2.75em;
20
+ height: 2.75em;
21
+ border-radius: 50%;
22
+ background: ${({theme}) => theme.sanity.color.card.enabled.bg};
23
+ opacity: 0.75;
24
+ }
25
+ `
26
+
27
+ const Root = styled(Flex)`
28
+ &:hover {
29
+ ${PlayIconBox} {
30
+ &:before {
31
+ opacity: 1;
32
+ }
33
+ }
34
+ }
35
+ `
36
+
37
+ const PosterCard = styled(Card)`
38
+ width: 100%;
39
+ padding-bottom: calc(9 / 16 * 100%);
40
+ position: relative;
41
+ `
42
+
43
+ const Poster = styled.img`
44
+ position: absolute;
45
+ top: 0;
46
+ left: 0;
47
+ height: 100%;
48
+ width: 100%;
49
+ object-fit: cover;
50
+ display: block;
51
+
52
+ &:not([src]) {
53
+ display: none;
54
+ }
55
+ `
56
+
57
+ class Tutorial extends React.PureComponent {
58
+ static propTypes = {
59
+ title: PropTypes.string.isRequired,
60
+ posterURL: PropTypes.string,
61
+ href: PropTypes.string.isRequired,
62
+ showPlayIcon: PropTypes.bool,
63
+ presenterName: PropTypes.string.isRequired,
64
+ presenterSubtitle: PropTypes.string.isRequired,
65
+ }
66
+ static defaultProps = {
67
+ posterURL: null,
68
+ showPlayIcon: false,
69
+ }
70
+
71
+ render() {
72
+ const {title, posterURL, showPlayIcon, href, presenterName, presenterSubtitle} = this.props
73
+
74
+ return (
75
+ <Root flex={1}>
76
+ <Card
77
+ sizing="border"
78
+ flex={1}
79
+ padding={2}
80
+ radius={2}
81
+ as="a"
82
+ href={href}
83
+ target="_blank"
84
+ rel="noopener noreferrer"
85
+ style={{position: 'relative'}}
86
+ >
87
+ <Flex direction="column" style={{height: '100%'}}>
88
+ {posterURL && (
89
+ <PosterCard marginBottom={1}>
90
+ <Poster src={posterURL} />
91
+ {showPlayIcon && (
92
+ <PlayIconBox display="flex">
93
+ <Text align="center">
94
+ <PlayIcon />
95
+ </Text>
96
+ </PlayIconBox>
97
+ )}
98
+ </PosterCard>
99
+ )}
100
+ <Flex direction="column" justify="space-between" paddingY={2} flex={1}>
101
+ <Heading as="h3" size={1}>
102
+ {title}
103
+ </Heading>
104
+ <Box marginTop={4}>
105
+ <Stack space={2} flex={1}>
106
+ <Text size={1}>{presenterName}</Text>
107
+ <Text size={0} style={{opacity: 0.7}}>
108
+ {presenterSubtitle}
109
+ </Text>
110
+ </Stack>
111
+ </Box>
112
+ </Flex>
113
+ </Flex>
114
+ </Card>
115
+ </Root>
116
+ )
117
+ }
118
+ }
119
+
120
+ export default Tutorial
@@ -0,0 +1,17 @@
1
+ import imageUrlBuilder from '@sanity/image-url'
2
+ import {versionedClient} from '../../versionedClient'
3
+
4
+ const tutorialsProjectConfig = {
5
+ projectId: '3do82whm',
6
+ dataset: 'next',
7
+ }
8
+
9
+ export default {
10
+ getFeed: (templateRepoId) => {
11
+ const uri = templateRepoId
12
+ ? `/addons/dashboard?templateRepoId=${templateRepoId}`
13
+ : '/addons/dashboard'
14
+ return versionedClient.observable.request({uri, withCredentials: false})
15
+ },
16
+ urlBuilder: imageUrlBuilder(tutorialsProjectConfig),
17
+ }
@@ -0,0 +1,7 @@
1
+ import SanityTutorials from './SanityTutorials'
2
+
3
+ export default {
4
+ name: 'sanity-tutorials',
5
+ component: SanityTutorials,
6
+ layout: {width: 'full'},
7
+ }