@sanity/dashboard 3.0.0 → 3.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/lib/index.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- var e,n,t,r,i,o,a,l,d,s,c,u,h,p,g,m,f,b,y,w;function v(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function j(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?v(Object(t),!0).forEach((function(n){x(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):v(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function x(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function O(e,n){return n||(n=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(n)}}))}import{jsxs as k,jsx as z,Fragment as P}from"react/jsx-runtime";import{forwardRef as _,createContext as S,useContext as R,useMemo as I,createElement as L,useState as q,useEffect as A,useCallback as E}from"react";import{Card as Y,Box as B,Heading as D,Button as H,Stack as M,Label as T,Grid as V,Text as X,Code as N,Spinner as U,Flex as C,Container as F}from"@sanity/ui";import G,{css as Q}from"styled-components";import{useClient as W,useUserStore as Z,DefaultPreview as J,definePlugin as K}from"sanity";import{from as $}from"rxjs";import{switchMap as ee,map as ne}from"rxjs/operators";import{RobotIcon as te,PlayIcon as re}from"@sanity/icons";import ie from"@sanity/image-url";const oe=G(Y)(e||(e=O(["\n display: flex;\n flex-direction: column;\n justify-content: stretch;\n height: 100%;\n box-sizing: border-box;\n position: relative;\n"]))),ae=G(Y)(n||(n=O(["\n position: sticky;\n top: 0;\n z-index: 2;\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n"]))),le=G(Y)(t||(t=O(["\n position: sticky;\n overflow: hidden;\n bottom: 0;\n z-index: 2;\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n margin-top: auto;\n"]))),de=G(B)(r||(r=O(["\n position: relative;\n z-index: 1;\n height: stretch;\n min-height: 21.5em;\n\n @media (min-width: ","px) {\n overflow-y: auto;\n outline: none;\n }\n"])),(e=>{let{theme:n}=e;return n.sanity.media[0]})),se=_((function(e,n){const{header:t,children:r,footer:i}=e;return k(oe,{radius:3,display:"flex",ref:n,children:[t&&z(ae,{borderBottom:!0,paddingX:3,paddingY:4,children:z(D,{size:1,textOverflow:"ellipsis",children:t})}),r&&z(de,{children:r}),i&&z(le,{borderTop:!0,children:i})]})}));function ce(){return W({apiVersion:"1"})}const ue=S({widgets:[]});function he(e){const n=R(ue),t=I((()=>j(j({},e.layout||{}),n.layout||{})),[e.layout,n.layout]);return z(Y,{shadow:1,"data-width":t.width,"data-height":t.height,children:L(e.component,{})})}function pe(e,n){return"https://".concat(e,".api.sanity.io/v1/groq/").concat(n)}function ge(e){return"https://manage.sanity.io/projects/".concat(e)}const me=[],fe=[];function be(e){const{__experimental_before:n=me,data:t=fe}=e,[r,i]=q(),[o,a]=q(),l=ce(),{projectId:d="unknown",dataset:s="unknown"}=l.config();A((()=>{const e=[];return e.push(l.observable.request({uri:"/projects/".concat(d)}).subscribe({next:e=>{const{studioHost:n}=e;i(n?"https://".concat(n,".sanity.studio"):void 0)},error:e=>{console.error("Error while looking for studioHost",e),i({error:"Something went wrong while looking up studioHost. See console."})}})),e.push(l.observable.request({method:"HEAD",uri:"/graphql/".concat(s,"/default")}).subscribe({next:()=>a(function(e,n){return"https://".concat(e,".api.sanity.io/v1/graphql/").concat(n,"/default")}(d,s)),error:e=>{404===e.statusCode?a(void 0):(console.error("Error while looking for graphqlApi",e),a({error:"Something went wrong while looking up graphqlApi. See console."}))}})),()=>{e.forEach((e=>e.unsubscribe()))}}),[s,d,l,a,i]);const c=I((()=>{var e;let n=[{title:"Sanity project",rows:[{title:"Project ID",value:d},{title:"Dataset",value:s}]}];const i=[r?{title:"Studio",value:r}:null,...t.filter((e=>"apps"===e.category))].filter((e=>!!e));i.length>0&&(n=n.concat([{title:"Apps",rows:i}])),n=n.concat([{title:"APIs",rows:[{title:"GROQ",value:pe(d,s)},{title:"GraphQL",value:null!=(e="object"==typeof o?"Error":o)?e:"Not deployed"}]}],t.filter((e=>"apis"===e.category)));const a={};return t.forEach((e=>{e.category&&"apps"!==e.category&&"apis"!==e.category&&(a[e.category]||(a[e.category]=[]),a[e.category].push(e))})),Object.keys(a).forEach((e=>{n.push({title:e,rows:a[e]})})),n}),[o,r,d,s,t]);return k(P,{children:[n.map(((e,n)=>z(he,j({},e),n))),z(B,{height:"fill",marginTop:(null==n?void 0:n.length)>0?4:0,children:z(se,{footer:z(H,{style:{width:"100%"},paddingX:2,paddingY:4,mode:"bleed",tone:"primary",text:"Manage project",as:"a",href:ge(d)}),children:z(Y,{paddingY:4,radius:2,role:"table","aria-label":"Project info","aria-describedby":"project_info_table",children:k(M,{space:4,children:[z(B,{paddingX:3,as:"header",children:z(D,{size:1,as:"h2",id:"project_info_table",children:"Project info"})}),c.map((e=>e&&e.rows?k(M,{space:3,children:[z(Y,{borderBottom:!0,padding:3,children:z(T,{size:0,muted:!0,role:"columnheader",children:e.title})}),z(M,{space:4,paddingX:3,role:"rowgroup",children:e.rows.map((e=>{var n,t;return k(V,{columns:2,role:"row",children:[z(X,{weight:"medium",role:"rowheader",children:e.title}),"object"==typeof e.value&&z(X,{size:1,children:null==(n=e.value)?void 0:n.error}),"string"==typeof e.value&&z(P,{children:(t=e.value,t&&/^https?:\/\//.test("".concat(t))?z(X,{size:1,role:"cell",style:{wordBreak:"break-word"},children:z("a",{href:e.value,children:e.value})}):z(N,{size:1,role:"cell",style:{wordBreak:"break-word"},children:e.value}))})]},e.title)}))})]},e.title):null))]})})})})]})}function ye(e){var n;return{name:"project-info",component:be,layout:null!=(n=null==e?void 0:e.layout)?n:{width:"medium"}}}const we=G(Y)(i||(i=O(["\n box-sizing: border-box;\n border-radius: 50%;\n border-color: transparent;\n overflow: hidden;\n width: 100%;\n height: 100%;\n\n & > img {\n width: 100%;\n height: auto;\n }\n"])));function ve(){const[e,n]=q(),[t,r]=q(),[i,o]=q(),a=Z(),l=ce(),d=E((()=>{const{projectId:e}=l.config(),t=l.observable.request({uri:"/projects/".concat(e)}).pipe(ee((e=>$(a.getUsers(e.members.map((e=>e.id)))).pipe(ne((n=>({project:e,users:n}))))))).subscribe({next:e=>{let{users:t,project:i}=e;n(i),r((Array.isArray(t)?t:[t]).sort(((e,n)=>function(e,n,t){const{members:r}=t,i=r.find((n=>n.id===(null==e?void 0:e.id))),o=r.find((e=>e.id===(null==n?void 0:n.id)));if(null==i?void 0:i.isRobot)return 1;if(null==o?void 0:o.isRobot)return-1;return 0}(e,n,i))))},error:e=>o(e)});return()=>t.unsubscribe()}),[a,l]);A((()=>d()),[d]);const s=E((()=>d()),[d]),c=!t||!e;return i?z(se,{header:"Project users",children:z(B,{padding:4,children:k(X,{children:["Something went wrong while fetching data. You could"," ",z("a",{onClick:s,title:"Retry users fetch",style:{cursor:"pointer"},children:"retry"}),"..?"]})})}):k(se,{header:"Project users",footer:z(H,{style:{width:"100%"},paddingX:2,paddingY:4,mode:"bleed",tone:"primary",text:"Invite members",as:"a",loading:c,href:c?void 0:(u=e.id,"https://manage.sanity.io/projects/".concat(u,"/team/invite"))}),children:[c&&z(B,{paddingY:5,paddingX:2,children:k(M,{space:4,children:[z(X,{align:"center",muted:!0,size:1,children:z(U,{})}),z(X,{align:"center",size:1,muted:!0,children:"Loading items..."})]})}),!c&&z(M,{space:3,padding:3,children:null==t?void 0:t.map((n=>{const t=e.members.find((e=>e.id===n.id)),r=(null==t?void 0:t.isRobot)?z(X,{size:3,children:z(te,{})}):z(we,{tone:"transparent",children:(null==n?void 0:n.imageUrl)&&z("img",{src:n.imageUrl,alt:null==n?void 0:n.displayName})});return z(B,{children:z(J,{title:n.displayName,subtitle:null==t?void 0:t.role,media:r})},n.id)}))})]});var u}function je(e){return{name:"project-info",component:ve,layout:null==e?void 0:e.layout}}const xe=G(B)(o||(o=O(["\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n\n &:before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 2.75em;\n height: 2.75em;\n border-radius: 50%;\n background: ",";\n opacity: 0.75;\n }\n"])),(e=>{let{theme:n}=e;return n.sanity.color.card.enabled.bg})),Oe=G(C)(a||(a=O(["\n &:hover {\n "," {\n &:before {\n opacity: 1;\n }\n }\n }\n"])),xe),ke=G(Y)(l||(l=O(["\n width: 100%;\n padding-bottom: calc(9 / 16 * 100%);\n position: relative;\n"]))),ze=G.img(d||(d=O(["\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n object-fit: cover;\n display: block;\n\n &:not([src]) {\n display: none;\n }\n"])));function Pe(e){const{title:n,posterURL:t,showPlayIcon:r,href:i,presenterName:o,presenterSubtitle:a}=e;return z(Oe,{flex:1,children:z(Y,{sizing:"border",flex:1,padding:2,radius:2,as:"a",href:i,target:"_blank",rel:"noopener noreferrer",style:{position:"relative"},children:k(C,{direction:"column",style:{height:"100%"},children:[t&&k(ke,{marginBottom:1,children:[z(ze,{src:t}),r&&z(xe,{display:"flex",children:z(X,{align:"center",children:z(re,{})})})]}),k(C,{direction:"column",justify:"space-between",paddingY:2,flex:1,children:[z(D,{as:"h3",size:1,children:n}),z(B,{marginTop:4,children:k(M,{space:2,flex:1,children:[z(X,{size:1,children:o}),z(X,{size:0,style:{opacity:.7},children:a})]})})]})]})})})}const _e={projectId:"3do82whm",dataset:"next"};function Se(e){const{templateRepoId:n}=e,[t,r]=q([]),{getFeed:i,urlBuilder:o}=function(){const e=ce();return I((()=>({getFeed:n=>{const t=n?"/addons/dashboard?templateRepoId=".concat(n):"/addons/dashboard";return e.observable.request({uri:t,withCredentials:!1})},urlBuilder:ie(_e)})),[e])}();A((()=>{const e=i(n).subscribe((e=>{r(e.items)}));return()=>{e.unsubscribe()}}),[r,i,n]);return z(se,{header:"Learn about Sanity",children:z(C,{as:"ul",overflow:"auto",align:"stretch",paddingY:2,children:null==t?void 0:t.map(((e,n)=>{var r;if(!e.title||!e.guideOrTutorial&&!e.externalLink)return null;const i=e.presenter||(null==(r=e.guideOrTutorial)?void 0:r.presenter)||{},a=e.category,{guideOrTutorial:l={}}=e,d=(l.slug?(s=l.slug,"tutorial"===(c=l._type)?"https://www.sanity.io/docs/tutorials/".concat(s.current):"guide"===c&&"https://www.sanity.io/docs/guides/".concat(s.current)):e.externalLink)||e.externalLink;var s,c;return z(C,{as:"li",paddingRight:n<(null==t?void 0:t.length)-1?1:3,paddingLeft:0===n?3:0,align:"stretch",style:{minWidth:272,width:"30%"},children:z(Pe,{title:e.title,href:null!=d?d:"",presenterName:i.name,presenterSubtitle:a,showPlayIcon:e.hasVideo,posterURL:e.poster?o.image(e.poster).height(360).url():void 0})},e._id)}))})})}function Re(e){var n;return{name:"sanity-tutorials",component:Se,layout:null!=(n=null==e?void 0:e.layout)?n:{width:"full"}}}function Ie(e){return z(F,{width:4,padding:4,sizing:"border",style:{minHeight:"100%"},children:e.children})}const Le=function(){return Q(s||(s=O(["\n @media (min-width: ","px) {\n ","\n }\n "])),(e=>{let{theme:n}=e;return n.sanity.media[0]}),Q(...arguments))},qe=function(){return Q(c||(c=O(["\n @media (min-width: ","px) {\n ","\n }\n "])),(e=>{let{theme:n}=e;return n.sanity.media[2]}),Q(...arguments))},Ae=G(V)(u||(u=O(["\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n\n & > div {\n overflow: hidden;\n }\n\n & > div[data-width='medium'] {\n ","\n }\n\n & > div[data-width='large'] {\n ","\n\n ","\n }\n\n & > div[data-width='full'] {\n ","\n }\n\n & > div[data-height='medium'] {\n ","\n }\n\n & > div[data-height='large'] {\n ","\n\n ","\n }\n\n & > div[data-height='full'] {\n ","\n }\n"])),Le(h||(h=O(["\n grid-column: span 2;\n "]))),Le(p||(p=O(["\n grid-column: span 2;\n "]))),qe(g||(g=O(["\n grid-column: span 3;\n "]))),Le(m||(m=O(["\n grid-column: 1 / -1;\n "]))),Le(f||(f=O(["\n grid-row: span 2;\n "]))),Le(b||(b=O(["\n grid-row: span 2;\n "]))),qe(y||(y=O(["\n grid-row: span 3;\n "]))),qe(w||(w=O(["\n grid-row: 1 / -1;\n "])))),Ee=[],Ye={};function Be(e){const{config:{layout:n=Ye,widgets:t=Ee}}=e;return k(Ae,{autoFlow:"row dense","data-width":n.width||"auto","data-height":n.height||"auto",gap:4,children:[t.length?null:z(Y,{padding:4,shadow:1,tone:"primary",children:z(X,{align:"center",children:"Add some widgets to populate this space."})}),t.map(((e,n)=>"__experimental_group"===e.type?z(Be,{config:e},n):e.component?z(he,j({},e),n):k(B,{children:[e.name," is missing widget component"]},n)))]})}function De(e){let{config:n}=e;return n?z(ue.Provider,{value:n,children:z(Ie,{children:z(Be,{config:n})})}):null}const He={stroke:"currentColor",strokeWidth:1.2},Me=()=>k("svg",{"data-sanity-icon":!0,viewBox:"0 0 25 25",fill:"none",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid",width:"1em",height:"1em",children:[z("path",{d:"M19.5 19.5H5.5V5.5H19.5V19.5Z",style:He}),z("path",{d:"M5.5 12.5H19.5",style:He}),z("path",{d:"M14.5 19.5V12.5M10.5 12.5V5.5",style:He})]}),Te=K((function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};var n,t;const r={layout:null!=(n=e.defaultLayout)?n:{},widgets:null!=(t=e.widgets)?t:[]};return{name:"dashboard",tools:(e,n)=>[...e,{title:"Dashboard",name:"dashboard",icon:Me,component:()=>z(De,{config:r})}]}}));export{se as DashboardWidgetContainer,Te as dashboardTool,ye as projectInfoWidget,je as projectUsersWidget,Re as sanityTutorialsWidget};
1
+ var e,n,t,r,i,o,l,a,d,s,c,u,h,p,g,m,f,b,y,w;function v(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function j(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?v(Object(t),!0).forEach((function(n){x(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):v(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function x(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function O(e,n){return n||(n=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(n)}}))}import{jsxs as k,jsx as z,Fragment as P}from"react/jsx-runtime";import{forwardRef as _,createContext as S,useContext as R,useMemo as I,createElement as L,useState as Y,useEffect as q,useCallback as A}from"react";import{Card as E,Box as B,Heading as D,Button as H,Stack as M,Label as T,Grid as V,Text as X,Code as N,Spinner as U,Flex as C,Container as F}from"@sanity/ui";import G,{css as Q}from"styled-components";import{useClient as W,useUserStore as Z,DefaultPreview as J,definePlugin as K}from"sanity";import{from as $}from"rxjs";import{switchMap as ee,map as ne}from"rxjs/operators";import{RobotIcon as te,PlayIcon as re}from"@sanity/icons";import ie from"@sanity/image-url";const oe=G(E)(e||(e=O(["\n display: flex;\n flex-direction: column;\n justify-content: stretch;\n height: 100%;\n box-sizing: border-box;\n position: relative;\n"]))),le=G(E)(n||(n=O(["\n position: sticky;\n top: 0;\n z-index: 2;\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n"]))),ae=G(E)(t||(t=O(["\n position: sticky;\n overflow: hidden;\n bottom: 0;\n z-index: 2;\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n margin-top: auto;\n"]))),de=G(B)(r||(r=O(["\n position: relative;\n z-index: 1;\n height: stretch;\n min-height: 21.5em;\n\n @media (min-width: ","px) {\n overflow-y: auto;\n outline: none;\n }\n"])),(e=>{let{theme:n}=e;return n.sanity.media[0]})),se=_((function(e,n){const{header:t,children:r,footer:i}=e;return k(oe,{radius:3,display:"flex",ref:n,children:[t&&z(le,{borderBottom:!0,paddingX:3,paddingY:4,children:z(D,{size:1,textOverflow:"ellipsis",children:t})}),r&&z(de,{children:r}),i&&z(ae,{borderTop:!0,children:i})]})}));function ce(){return W({apiVersion:"1"})}const ue=S({widgets:[]});function he(e){const n=R(ue),t=I((()=>j(j({},e.layout||{}),n.layout||{})),[e.layout,n.layout]);return z(E,{shadow:1,"data-width":t.width,"data-height":t.height,children:L(e.component,{})})}function pe(e,n){return"https://".concat(e,".api.sanity.io/v1/groq/").concat(n)}function ge(e){return"https://manage.sanity.io/projects/".concat(e)}const me=[],fe=[];function be(e){const{__experimental_before:n=me,data:t=fe}=e,[r,i]=Y(),[o,l]=Y(),a=ce(),{projectId:d="unknown",dataset:s="unknown"}=a.config();q((()=>{const e=[];return e.push(a.observable.request({uri:"/projects/".concat(d)}).subscribe({next:e=>{const{studioHost:n}=e;i(n?"https://".concat(n,".sanity.studio"):void 0)},error:e=>{console.error("Error while looking for studioHost",e),i({error:"Something went wrong while looking up studioHost. See console."})}})),e.push(a.observable.request({method:"HEAD",uri:"/graphql/".concat(s,"/default")}).subscribe({next:()=>l(function(e,n){return"https://".concat(e,".api.sanity.io/v1/graphql/").concat(n,"/default")}(d,s)),error:e=>{404===e.statusCode?l(void 0):(console.error("Error while looking for graphqlApi",e),l({error:"Something went wrong while looking up graphqlApi. See console."}))}})),()=>{e.forEach((e=>e.unsubscribe()))}}),[s,d,a,l,i]);const c=I((()=>{var e;let n=[{title:"Sanity project",rows:[{title:"Project ID",value:d},{title:"Dataset",value:s}]}];const i=[r?{title:"Studio",value:r}:null,...t.filter((e=>"apps"===e.category))].filter((e=>!!e));i.length>0&&(n=n.concat([{title:"Apps",rows:i}])),n=n.concat([{title:"APIs",rows:[{title:"GROQ",value:pe(d,s)},{title:"GraphQL",value:null!=(e="object"==typeof o?"Error":o)?e:"Not deployed"}]}],t.filter((e=>"apis"===e.category)));const l={};return t.forEach((e=>{e.category&&"apps"!==e.category&&"apis"!==e.category&&(l[e.category]||(l[e.category]=[]),l[e.category].push(e))})),Object.keys(l).forEach((e=>{n.push({title:e,rows:l[e]})})),n}),[o,r,d,s,t]);return k(P,{children:[n.map(((e,n)=>z(he,j({},e),n))),z(B,{height:"fill",marginTop:(null==n?void 0:n.length)>0?4:0,children:z(se,{footer:z(H,{style:{width:"100%"},paddingX:2,paddingY:4,mode:"bleed",tone:"primary",text:"Manage project",as:"a",href:ge(d)}),children:z(E,{paddingY:4,radius:2,role:"table","aria-label":"Project info","aria-describedby":"project_info_table",children:k(M,{space:4,children:[z(B,{paddingX:3,as:"header",children:z(D,{size:1,as:"h2",id:"project_info_table",children:"Project info"})}),c.map((e=>e&&e.rows?k(M,{space:3,children:[z(E,{borderBottom:!0,padding:3,children:z(T,{size:0,muted:!0,role:"columnheader",children:e.title})}),z(M,{space:4,paddingX:3,role:"rowgroup",children:e.rows.map((e=>{var n,t;return k(V,{columns:2,role:"row",children:[z(X,{weight:"medium",role:"rowheader",children:e.title}),"object"==typeof e.value&&z(X,{size:1,children:null==(n=e.value)?void 0:n.error}),"string"==typeof e.value&&z(P,{children:(t=e.value,t&&/^https?:\/\//.test("".concat(t))?z(X,{size:1,role:"cell",style:{wordBreak:"break-word"},children:z("a",{href:e.value,children:e.value})}):z(N,{size:1,role:"cell",style:{wordBreak:"break-word"},children:e.value}))})]},e.title)}))})]},e.title):null))]})})})})]})}function ye(e){var n;return{name:"project-info",component:be,layout:null!=(n=null==e?void 0:e.layout)?n:{width:"medium"}}}const we=G(E)(i||(i=O(["\n box-sizing: border-box;\n border-radius: 50%;\n border-color: transparent;\n overflow: hidden;\n width: 100%;\n height: 100%;\n\n & > img {\n width: 100%;\n height: auto;\n }\n"])));function ve(){const[e,n]=Y(),[t,r]=Y(),[i,o]=Y(),l=Z(),a=ce(),d=A((()=>{const{projectId:e}=a.config(),t=a.observable.request({uri:"/projects/".concat(e)}).pipe(ee((e=>$(l.getUsers(e.members.map((e=>e.id)))).pipe(ne((n=>({project:e,users:n}))))))).subscribe({next:e=>{let{users:t,project:i}=e;n(i),r((Array.isArray(t)?t:[t]).sort(((e,n)=>function(e,n,t){const{members:r}=t,i=r.find((n=>n.id===(null==e?void 0:e.id))),o=r.find((e=>e.id===(null==n?void 0:n.id)));if(null==i?void 0:i.isRobot)return 1;if(null==o?void 0:o.isRobot)return-1;return 0}(e,n,i))))},error:e=>o(e)});return()=>t.unsubscribe()}),[l,a]);q((()=>d()),[d]);const s=A((()=>d()),[d]),c=!t||!e;return i?z(se,{header:"Project users",children:z(B,{padding:4,children:k(X,{children:["Something went wrong while fetching data. You could"," ",z("a",{onClick:s,title:"Retry users fetch",style:{cursor:"pointer"},children:"retry"}),"..?"]})})}):k(se,{header:"Project users",footer:z(H,{style:{width:"100%"},paddingX:2,paddingY:4,mode:"bleed",tone:"primary",text:"Invite members",as:"a",loading:c,href:c?void 0:(u=e.id,"https://manage.sanity.io/projects/".concat(u,"/team/invite"))}),children:[c&&z(B,{paddingY:5,paddingX:2,children:k(M,{space:4,children:[z(X,{align:"center",muted:!0,size:1,children:z(U,{})}),z(X,{align:"center",size:1,muted:!0,children:"Loading items..."})]})}),!c&&z(M,{space:3,padding:3,children:null==t?void 0:t.map((n=>{const t=e.members.find((e=>e.id===n.id)),r=(null==t?void 0:t.isRobot)?z(X,{size:3,children:z(te,{})}):z(we,{tone:"transparent",children:(null==n?void 0:n.imageUrl)&&z("img",{src:n.imageUrl,alt:null==n?void 0:n.displayName})});return z(B,{children:z(J,{title:n.displayName,subtitle:null==t?void 0:t.role,media:r})},n.id)}))})]});var u}function je(e){return{name:"project-info",component:ve,layout:null==e?void 0:e.layout}}const xe=G(B)(o||(o=O(["\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n\n &:before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 2.75em;\n height: 2.75em;\n border-radius: 50%;\n background: ",";\n opacity: 0.75;\n }\n"])),(e=>{let{theme:n}=e;return n.sanity.color.card.enabled.bg})),Oe=G(C)(l||(l=O(["\n &:hover {\n "," {\n &:before {\n opacity: 1;\n }\n }\n }\n"])),xe),ke=G(E)(a||(a=O(["\n width: 100%;\n padding-bottom: calc(9 / 16 * 100%);\n position: relative;\n"]))),ze=G.img(d||(d=O(["\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n object-fit: cover;\n display: block;\n\n &:not([src]) {\n display: none;\n }\n"])));function Pe(e){const{title:n,posterURL:t,showPlayIcon:r,href:i,presenterName:o,presenterSubtitle:l}=e;return z(Oe,{flex:1,children:z(E,{sizing:"border",flex:1,padding:2,radius:2,as:"a",href:i,target:"_blank",rel:"noopener noreferrer",style:{position:"relative"},children:k(C,{direction:"column",style:{height:"100%"},children:[t&&k(ke,{marginBottom:1,children:[z(ze,{src:t}),r&&z(xe,{display:"flex",children:z(X,{align:"center",children:z(re,{})})})]}),k(C,{direction:"column",justify:"space-between",paddingY:2,flex:1,children:[z(D,{as:"h3",size:1,children:n}),z(B,{marginTop:4,children:k(M,{space:2,flex:1,children:[z(X,{size:1,children:o}),z(X,{size:0,style:{opacity:.7},children:l})]})})]})]})})})}const _e={projectId:"3do82whm",dataset:"next"};function Se(e){const{templateRepoId:n}=e,[t,r]=Y([]),{getFeed:i,urlBuilder:o}=function(){const e=ce();return I((()=>({getFeed:n=>{const t=n?"/addons/dashboard?templateRepoId=".concat(n):"/addons/dashboard";return e.observable.request({uri:t,withCredentials:!1})},urlBuilder:ie(_e)})),[e])}();q((()=>{const e=i(n).subscribe((e=>{r(e.items)}));return()=>{e.unsubscribe()}}),[r,i,n]);return z(se,{header:"Learn about Sanity",children:z(C,{as:"ul",overflow:"auto",align:"stretch",paddingY:2,children:null==t?void 0:t.map(((e,n)=>{var r;if(!e.title||!e.guideOrTutorial&&!e.externalLink)return null;const i=e.presenter||(null==(r=e.guideOrTutorial)?void 0:r.presenter)||{},l=e.category,{guideOrTutorial:a={}}=e,d=(a.slug?(s=a.slug,"tutorial"===(c=a._type)?"https://www.sanity.io/docs/tutorials/".concat(s.current):"guide"===c&&"https://www.sanity.io/docs/guides/".concat(s.current)):e.externalLink)||e.externalLink;var s,c;return z(C,{as:"li",paddingRight:n<(null==t?void 0:t.length)-1?1:3,paddingLeft:0===n?3:0,align:"stretch",style:{minWidth:272,width:"30%"},children:z(Pe,{title:e.title,href:null!=d?d:"",presenterName:i.name,presenterSubtitle:l,showPlayIcon:e.hasVideo,posterURL:e.poster?o.image(e.poster).height(360).url():void 0})},e._id)}))})})}function Re(e){var n;return{name:"sanity-tutorials",component:Se,layout:null!=(n=null==e?void 0:e.layout)?n:{width:"full"}}}function Ie(e){return z(F,{width:4,padding:4,sizing:"border",style:{height:"100%",overflowY:"auto"},children:e.children})}const Le=function(){return Q(s||(s=O(["\n @media (min-width: ","px) {\n ","\n }\n "])),(e=>{let{theme:n}=e;return n.sanity.media[0]}),Q(...arguments))},Ye=function(){return Q(c||(c=O(["\n @media (min-width: ","px) {\n ","\n }\n "])),(e=>{let{theme:n}=e;return n.sanity.media[2]}),Q(...arguments))},qe=G(V)(u||(u=O(["\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n\n & > div {\n overflow: hidden;\n }\n\n & > div[data-width='medium'] {\n ","\n }\n\n & > div[data-width='large'] {\n ","\n\n ","\n }\n\n & > div[data-width='full'] {\n ","\n }\n\n & > div[data-height='medium'] {\n ","\n }\n\n & > div[data-height='large'] {\n ","\n\n ","\n }\n\n & > div[data-height='full'] {\n ","\n }\n"])),Le(h||(h=O(["\n grid-column: span 2;\n "]))),Le(p||(p=O(["\n grid-column: span 2;\n "]))),Ye(g||(g=O(["\n grid-column: span 3;\n "]))),Le(m||(m=O(["\n grid-column: 1 / -1;\n "]))),Le(f||(f=O(["\n grid-row: span 2;\n "]))),Le(b||(b=O(["\n grid-row: span 2;\n "]))),Ye(y||(y=O(["\n grid-row: span 3;\n "]))),Ye(w||(w=O(["\n grid-row: 1 / -1;\n "])))),Ae=[],Ee={};function Be(e){const{config:{layout:n=Ee,widgets:t=Ae}}=e;return k(qe,{autoFlow:"row dense","data-width":n.width||"auto","data-height":n.height||"auto",gap:4,children:[t.length?null:z(E,{padding:4,shadow:1,tone:"primary",children:z(X,{align:"center",children:"Add some widgets to populate this space."})}),t.map(((e,n)=>"__experimental_group"===e.type?z(Be,{config:e},n):e.component?z(he,j({},e),n):k(B,{children:[e.name," is missing widget component"]},n)))]})}function De(e){let{config:n}=e;return n?z(ue.Provider,{value:n,children:z(Ie,{children:z(Be,{config:n})})}):null}const He={stroke:"currentColor",strokeWidth:1.2},Me=()=>k("svg",{"data-sanity-icon":!0,viewBox:"0 0 25 25",fill:"none",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid",width:"1em",height:"1em",children:[z("path",{d:"M19.5 19.5H5.5V5.5H19.5V19.5Z",style:He}),z("path",{d:"M5.5 12.5H19.5",style:He}),z("path",{d:"M14.5 19.5V12.5M10.5 12.5V5.5",style:He})]}),Te=K((function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};var n,t,r,i,o;const l={layout:null!=(n=e.defaultLayout)?n:{},widgets:null!=(t=e.widgets)?t:[]},a=null!=(r=e.title)?r:"Dashboard",d=null!=(i=e.name)?i:"dashboard",s=null!=(o=e.icon)?o:Me;return{name:"dashboard",tools:(e,n)=>[...e,{title:a,name:d,icon:s,component:()=>z(De,{config:l})}]}}));export{se as DashboardWidgetContainer,Te as dashboardTool,ye as projectInfoWidget,je as projectUsersWidget,Re as sanityTutorialsWidget};
2
2
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/components/DashboardWidgetContainer.tsx","../src/versionedClient.ts","../src/containers/DashboardContext.tsx","../src/containers/WidgetContainer.tsx","../src/widgets/projectInfo/ProjectInfo.tsx","../src/widgets/projectInfo/index.ts","../src/widgets/projectUsers/ProjectUsers.tsx","../src/widgets/projectUsers/index.ts","../src/widgets/sanityTutorials/Tutorial.tsx","../src/widgets/sanityTutorials/dataAdapter.ts","../src/widgets/sanityTutorials/SanityTutorials.tsx","../src/widgets/sanityTutorials/index.ts","../src/components/DashboardLayout.tsx","../src/components/WidgetGroup.tsx","../src/containers/Dashboard.tsx","../src/plugin.tsx"],"sourcesContent":["import React, {forwardRef} from 'react'\nimport {Card, Box, Heading} from '@sanity/ui'\nimport styled from 'styled-components'\n\nconst Root = styled(Card)`\n display: flex;\n flex-direction: column;\n justify-content: stretch;\n height: 100%;\n box-sizing: border-box;\n position: relative;\n`\n\nconst Header = styled(Card)`\n position: sticky;\n top: 0;\n z-index: 2;\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n`\n\nconst Footer = styled(Card)`\n position: sticky;\n overflow: hidden;\n bottom: 0;\n z-index: 2;\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n margin-top: auto;\n`\n\nconst Content = styled(Box)`\n position: relative;\n z-index: 1;\n height: stretch;\n min-height: 21.5em;\n\n @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {\n overflow-y: auto;\n outline: none;\n }\n`\n\ninterface DashboardWidgetProps {\n header?: string\n children: React.ReactNode\n footer?: React.ReactNode\n}\n\nexport const DashboardWidgetContainer = forwardRef(function DashboardWidgetContainer(\n props: DashboardWidgetProps,\n ref: React.Ref<HTMLDivElement>\n) {\n const {header, children, footer} = props\n\n return (\n <Root radius={3} display=\"flex\" ref={ref}>\n {header && (\n <Header borderBottom paddingX={3} paddingY={4}>\n <Heading size={1} textOverflow=\"ellipsis\">\n {header}\n </Heading>\n </Header>\n )}\n {children && <Content>{children}</Content>}\n {footer && <Footer borderTop>{footer}</Footer>}\n </Root>\n )\n})\n","import {useClient} from 'sanity'\n\nexport function useVersionedClient() {\n return useClient({apiVersion: '1'})\n}\n","import {createContext, useContext} from 'react'\nimport {DashboardConfig} from '../types'\n\nexport const DashboardContext = createContext<DashboardConfig>({widgets: []})\n\nexport function useDashboardConfig(): DashboardConfig {\n return useContext(DashboardContext)\n}\n","import React, {createElement, useMemo} from 'react'\nimport {useDashboardConfig} from './DashboardContext'\nimport {Card} from '@sanity/ui'\nimport {DashboardWidget} from '../types'\n\nexport function WidgetContainer(props: DashboardWidget) {\n const config = useDashboardConfig()\n const layout = useMemo(\n () => ({\n ...(props.layout || {}),\n ...(config.layout || {}),\n }),\n [props.layout, config.layout]\n )\n\n return (\n <Card shadow={1} data-width={layout.width} data-height={layout.height}>\n {createElement(props.component, {})}\n </Card>\n )\n}\n","import React, {useEffect, useMemo, useState} from 'react'\nimport {Box, Card, Stack, Heading, Grid, Label, Text, Code, Button} from '@sanity/ui'\nimport {useVersionedClient} from '../../versionedClient'\nimport {Subscription} from 'rxjs'\nimport {WidgetContainer} from '../../containers/WidgetContainer'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\nimport {DashboardWidget} from '../../types'\n\nexport interface ProjectInfoProps {\n __experimental_before?: DashboardWidget[]\n data: ProjectData[]\n}\n\ninterface App {\n title: string\n rows?: App[]\n value?: string | {error: string}\n}\n\ninterface ProjectData {\n title: string\n category?: string\n}\n\nfunction isUrl(url?: string) {\n return url && /^https?:\\/\\//.test(`${url}`)\n}\n\nfunction getGraphQlUrl(projectId: string, dataset: string) {\n return `https://${projectId}.api.sanity.io/v1/graphql/${dataset}/default`\n}\n\nfunction getGroqUrl(projectId: string, dataset: string) {\n return `https://${projectId}.api.sanity.io/v1/groq/${dataset}`\n}\n\nfunction getManageUrl(projectId: string) {\n return `https://manage.sanity.io/projects/${projectId}`\n}\n\nconst NO_EXPERIMENTAL: DashboardWidget[] = []\nconst NO_DATA: ProjectData[] = []\n\nexport function ProjectInfo(props: ProjectInfoProps) {\n const {__experimental_before = NO_EXPERIMENTAL, data = NO_DATA} = props\n const [studioHost, setStudioHost] = useState<string | {error: string} | undefined>()\n const [graphqlApi, setGraphQlApi] = useState<string | {error: string} | undefined>()\n const versionedClient = useVersionedClient()\n const {projectId = 'unknown', dataset = 'unknown'} = versionedClient.config()\n\n useEffect(() => {\n const subscriptions: Subscription[] = []\n\n subscriptions.push(\n versionedClient.observable\n .request<{studioHost: string}>({uri: `/projects/${projectId}`})\n .subscribe({\n next: (result) => {\n const {studioHost: host} = result\n setStudioHost(host ? `https://${host}.sanity.studio` : undefined)\n },\n error: (error) => {\n console.error('Error while looking for studioHost', error)\n setStudioHost({\n error: 'Something went wrong while looking up studioHost. See console.',\n })\n },\n })\n )\n\n // ping assumed graphql endpoint\n subscriptions.push(\n versionedClient.observable\n .request({\n method: 'HEAD',\n uri: `/graphql/${dataset}/default`,\n })\n .subscribe({\n next: () => setGraphQlApi(getGraphQlUrl(projectId, dataset)),\n error: (error) => {\n if (error.statusCode === 404) {\n setGraphQlApi(undefined)\n } else {\n console.error('Error while looking for graphqlApi', error)\n setGraphQlApi({\n error: 'Something went wrong while looking up graphqlApi. See console.',\n })\n }\n },\n })\n )\n\n return () => {\n subscriptions.forEach((s) => s.unsubscribe())\n }\n }, [dataset, projectId, versionedClient, setGraphQlApi, setStudioHost])\n\n const assembleTableRows = useMemo(() => {\n let result: App[] = [\n {\n title: 'Sanity project',\n rows: [\n {title: 'Project ID', value: projectId},\n {title: 'Dataset', value: dataset},\n ],\n },\n ]\n\n // Handle any apps\n const apps: App[] = [\n studioHost ? {title: 'Studio', value: studioHost} : null,\n ...data.filter((item) => item.category === 'apps'),\n ].filter((a): a is App => !!a)\n if (apps.length > 0) {\n result = result.concat([{title: 'Apps', rows: apps}])\n }\n\n // Handle APIs\n result = result.concat(\n [\n {\n title: 'APIs',\n rows: [\n {title: 'GROQ', value: getGroqUrl(projectId, dataset)},\n {\n title: 'GraphQL',\n value: (typeof graphqlApi === 'object' ? 'Error' : graphqlApi) ?? 'Not deployed',\n },\n ],\n },\n ],\n data.filter((item) => item.category === 'apis')\n )\n\n // Handle whatever else there might be\n const otherStuff: Record<string, ProjectData[]> = {}\n data.forEach((item) => {\n if (item.category && item.category !== 'apps' && item.category !== 'apis') {\n if (!otherStuff[item.category]) {\n otherStuff[item.category] = []\n }\n otherStuff[item.category].push(item)\n }\n })\n Object.keys(otherStuff).forEach((category) => {\n result.push({title: category, rows: otherStuff[category]})\n })\n\n return result\n }, [graphqlApi, studioHost, projectId, dataset, data])\n\n return (\n <>\n {__experimental_before.map((widgetConfig, idx) => (\n <WidgetContainer key={idx} {...widgetConfig} />\n ))}\n <Box height=\"fill\" marginTop={__experimental_before?.length > 0 ? 4 : 0}>\n <DashboardWidgetContainer\n footer={\n <Button\n style={{width: '100%'}}\n paddingX={2}\n paddingY={4}\n mode=\"bleed\"\n tone=\"primary\"\n text=\"Manage project\"\n as=\"a\"\n href={getManageUrl(projectId)}\n />\n }\n >\n <Card\n paddingY={4}\n radius={2}\n role=\"table\"\n aria-label=\"Project info\"\n aria-describedby=\"project_info_table\"\n >\n <Stack space={4}>\n <Box paddingX={3} as=\"header\">\n <Heading size={1} as=\"h2\" id=\"project_info_table\">\n Project info\n </Heading>\n </Box>\n {assembleTableRows.map((item) => {\n if (!item || !item.rows) {\n return null\n }\n\n return (\n <Stack key={item.title} space={3}>\n <Card borderBottom padding={3}>\n <Label size={0} muted role=\"columnheader\">\n {item.title}\n </Label>\n </Card>\n <Stack space={4} paddingX={3} role=\"rowgroup\">\n {item.rows.map((row) => {\n return (\n <Grid key={row.title} columns={2} role=\"row\">\n <Text weight=\"medium\" role=\"rowheader\">\n {row.title}\n </Text>\n {typeof row.value === 'object' && (\n <Text size={1}>{row.value?.error}</Text>\n )}\n {typeof row.value === 'string' && (\n <>\n {isUrl(row.value) ? (\n <Text size={1} role=\"cell\" style={{wordBreak: 'break-word'}}>\n <a href={row.value}>{row.value}</a>\n </Text>\n ) : (\n <Code size={1} role=\"cell\" style={{wordBreak: 'break-word'}}>\n {row.value}\n </Code>\n )}\n </>\n )}\n </Grid>\n )\n })}\n </Stack>\n </Stack>\n )\n })}\n </Stack>\n </Card>\n </DashboardWidgetContainer>\n </Box>\n </>\n )\n}\n","import {ProjectInfo} from './ProjectInfo'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function projectInfoWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'project-info',\n component: ProjectInfo,\n layout: config?.layout ?? {width: 'medium'},\n }\n}\n","import React, {useCallback, useEffect, useState} from 'react'\nimport {from} from 'rxjs'\nimport {map, switchMap} from 'rxjs/operators'\nimport {Stack, Spinner, Card, Box, Text, Button} from '@sanity/ui'\nimport {RobotIcon} from '@sanity/icons'\nimport styled from 'styled-components'\nimport {DefaultPreview, useUserStore} from 'sanity'\nimport {useVersionedClient} from '../../versionedClient'\nimport {User} from 'sanity'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\n\nconst AvatarWrapper = styled(Card)`\n box-sizing: border-box;\n border-radius: 50%;\n border-color: transparent;\n overflow: hidden;\n width: 100%;\n height: 100%;\n\n & > img {\n width: 100%;\n height: auto;\n }\n`\n\nfunction getInviteUrl(projectId: string) {\n return `https://manage.sanity.io/projects/${projectId}/team/invite`\n}\n\ninterface Member {\n id: string\n role: string\n isRobot: boolean\n}\n\ninterface Project {\n id: string\n members: Member[]\n}\n\nexport function ProjectUsers() {\n const [project, setProject] = useState<Project | undefined>()\n const [users, setUsers] = useState<User[] | undefined>()\n const [error, setError] = useState<Error | undefined>()\n\n const userStore = useUserStore()\n const versionedClient = useVersionedClient()\n\n const fetchData = useCallback(() => {\n const {projectId} = versionedClient.config()\n const subscription = versionedClient.observable\n .request<Project>({\n uri: `/projects/${projectId}`,\n })\n .pipe(\n switchMap((_project) =>\n from(userStore.getUsers(_project.members.map((mem) => mem.id))).pipe(\n map((_users) => ({project: _project, users: _users}))\n )\n )\n )\n .subscribe({\n next: ({users: _users, project: _project}) => {\n setProject(_project)\n setUsers(\n (Array.isArray(_users) ? _users : [_users]).sort((userA, userB) =>\n sortUsersByRobotStatus(userA, userB, _project)\n )\n )\n },\n error: (e: Error) => setError(e),\n })\n\n return () => subscription.unsubscribe()\n }, [userStore, versionedClient])\n\n useEffect(() => fetchData(), [fetchData])\n\n const handleRetryFetch = useCallback(() => fetchData(), [fetchData])\n\n const isLoading = !users || !project\n\n if (error) {\n return (\n <DashboardWidgetContainer header=\"Project users\">\n <Box padding={4}>\n <Text>\n Something went wrong while fetching data. You could{' '}\n <a onClick={handleRetryFetch} title=\"Retry users fetch\" style={{cursor: 'pointer'}}>\n retry\n </a>\n ..?\n </Text>\n </Box>\n </DashboardWidgetContainer>\n )\n }\n\n return (\n <DashboardWidgetContainer\n header=\"Project users\"\n footer={\n <Button\n style={{width: '100%'}}\n paddingX={2}\n paddingY={4}\n mode=\"bleed\"\n tone=\"primary\"\n text=\"Invite members\"\n as=\"a\"\n loading={isLoading}\n href={isLoading ? undefined : getInviteUrl(project.id)}\n />\n }\n >\n {isLoading && (\n <Box paddingY={5} paddingX={2}>\n <Stack space={4}>\n <Text align=\"center\" muted size={1}>\n <Spinner />\n </Text>\n <Text align=\"center\" size={1} muted>\n Loading items...\n </Text>\n </Stack>\n </Box>\n )}\n\n {!isLoading && (\n <Stack space={3} padding={3}>\n {users?.map((user) => {\n const membership = project.members.find((member) => member.id === user.id)\n const media = membership?.isRobot ? (\n <Text size={3}>\n <RobotIcon />\n </Text>\n ) : (\n <AvatarWrapper tone=\"transparent\">\n {user?.imageUrl && <img src={user.imageUrl} alt={user?.displayName} />}\n </AvatarWrapper>\n )\n return (\n <Box key={user.id}>\n <DefaultPreview\n title={user.displayName}\n subtitle={membership?.role}\n media={media}\n />\n </Box>\n )\n })}\n </Stack>\n )}\n </DashboardWidgetContainer>\n )\n}\n\nfunction sortUsersByRobotStatus(userA: User, userB: User, project: Project) {\n const {members} = project\n const membershipA = members.find((member) => member.id === userA?.id)\n const membershipB = members.find((member) => member.id === userB?.id)\n if (membershipA?.isRobot) {\n return 1\n }\n if (membershipB?.isRobot) {\n return -1\n }\n return 0\n}\n","import {ProjectUsers} from './ProjectUsers'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function projectUsersWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'project-info',\n component: ProjectUsers,\n layout: config?.layout,\n }\n}\n","import React from 'react'\nimport {Card, Box, Heading, Flex, Text, Stack} from '@sanity/ui'\nimport {PlayIcon} from '@sanity/icons'\nimport styled from 'styled-components'\n\nconst PlayIconBox = styled(Box)`\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n\n &:before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 2.75em;\n height: 2.75em;\n border-radius: 50%;\n background: ${({theme}) => theme.sanity.color.card.enabled.bg};\n opacity: 0.75;\n }\n`\n\nconst Root = styled(Flex)`\n &:hover {\n ${PlayIconBox} {\n &:before {\n opacity: 1;\n }\n }\n }\n`\n\nconst PosterCard = styled(Card)`\n width: 100%;\n padding-bottom: calc(9 / 16 * 100%);\n position: relative;\n`\n\nconst Poster = styled.img`\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n object-fit: cover;\n display: block;\n\n &:not([src]) {\n display: none;\n }\n`\n\nexport interface TutorialProps {\n title: string\n posterURL?: string\n href: string\n showPlayIcon?: boolean\n presenterName?: string\n presenterSubtitle?: string\n}\n\nexport function Tutorial(props: TutorialProps) {\n const {title, posterURL, showPlayIcon, href, presenterName, presenterSubtitle} = props\n\n return (\n <Root flex={1}>\n <Card\n sizing=\"border\"\n flex={1}\n padding={2}\n radius={2}\n as=\"a\"\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{position: 'relative'}}\n >\n <Flex direction=\"column\" style={{height: '100%'}}>\n {posterURL && (\n <PosterCard marginBottom={1}>\n <Poster src={posterURL} />\n {showPlayIcon && (\n <PlayIconBox display=\"flex\">\n <Text align=\"center\">\n <PlayIcon />\n </Text>\n </PlayIconBox>\n )}\n </PosterCard>\n )}\n <Flex direction=\"column\" justify=\"space-between\" paddingY={2} flex={1}>\n <Heading as=\"h3\" size={1}>\n {title}\n </Heading>\n <Box marginTop={4}>\n <Stack space={2} flex={1}>\n <Text size={1}>{presenterName}</Text>\n <Text size={0} style={{opacity: 0.7}}>\n {presenterSubtitle}\n </Text>\n </Stack>\n </Box>\n </Flex>\n </Flex>\n </Card>\n </Root>\n )\n}\n","import {useMemo} from 'react'\nimport {useVersionedClient} from '../../versionedClient'\nimport imageUrlBuilder from '@sanity/image-url'\n\nconst tutorialsProjectConfig = {\n projectId: '3do82whm',\n dataset: 'next',\n}\n\nexport interface Guide {\n _type?: string\n slug?: {current: string}\n presenter?: {\n name?: string\n }\n}\n\nexport interface FeedItem {\n _id: string\n title?: string\n poster?: string\n category?: string\n guideOrTutorial?: Guide\n externalLink?: string\n presenter?: {\n name?: string\n }\n hasVideo?: boolean\n}\n\nexport function useDataAdapter() {\n const versionedClient = useVersionedClient()\n return useMemo(\n () => ({\n getFeed: (templateRepoId: string) => {\n const uri = templateRepoId\n ? `/addons/dashboard?templateRepoId=${templateRepoId}`\n : '/addons/dashboard'\n return versionedClient.observable.request<{items: FeedItem[]}>({\n uri,\n withCredentials: false,\n })\n },\n urlBuilder: imageUrlBuilder(tutorialsProjectConfig),\n }),\n [versionedClient]\n )\n}\n","import React, {useEffect, useState} from 'react'\nimport {Flex} from '@sanity/ui'\nimport {Tutorial} from './Tutorial'\nimport {FeedItem, Guide, useDataAdapter} from './dataAdapter'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\n\nfunction createUrl(slug: {current: string}, type?: string) {\n if (type === 'tutorial') {\n return `https://www.sanity.io/docs/tutorials/${slug.current}`\n } else if (type === 'guide') {\n return `https://www.sanity.io/docs/guides/${slug.current}`\n }\n return false\n}\n\nexport interface SanityTutorialsProps {\n templateRepoId: string\n}\n\nexport function SanityTutorials(props: SanityTutorialsProps) {\n const {templateRepoId} = props\n const [feedItems, setFeedItems] = useState<FeedItem[]>([])\n\n const {getFeed, urlBuilder} = useDataAdapter()\n\n useEffect(() => {\n const subscription = getFeed(templateRepoId).subscribe((response) => {\n setFeedItems(response.items)\n })\n return () => {\n subscription.unsubscribe()\n }\n }, [setFeedItems, getFeed, templateRepoId])\n\n const title = 'Learn about Sanity'\n\n return (\n <DashboardWidgetContainer header={title}>\n <Flex as=\"ul\" overflow=\"auto\" align=\"stretch\" paddingY={2}>\n {feedItems?.map((feedItem, index) => {\n if (!feedItem.title || (!feedItem.guideOrTutorial && !feedItem.externalLink)) {\n return null\n }\n const presenter = feedItem.presenter || feedItem.guideOrTutorial?.presenter || {}\n const subtitle = feedItem.category\n const {guideOrTutorial = {} as Guide} = feedItem\n const href =\n (guideOrTutorial.slug\n ? createUrl(guideOrTutorial.slug, guideOrTutorial._type)\n : feedItem.externalLink) || feedItem.externalLink\n\n return (\n <Flex\n as=\"li\"\n key={feedItem._id}\n paddingRight={index < feedItems?.length - 1 ? 1 : 3}\n paddingLeft={index === 0 ? 3 : 0}\n align=\"stretch\"\n style={{minWidth: 272, width: '30%'}}\n >\n <Tutorial\n title={feedItem.title}\n href={href ?? ''}\n presenterName={presenter.name}\n presenterSubtitle={subtitle}\n showPlayIcon={feedItem.hasVideo}\n posterURL={\n feedItem.poster ? urlBuilder.image(feedItem.poster).height(360).url() : undefined\n }\n />\n </Flex>\n )\n })}\n </Flex>\n </DashboardWidgetContainer>\n )\n}\n","import {SanityTutorials} from './SanityTutorials'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function sanityTutorialsWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'sanity-tutorials',\n component: SanityTutorials,\n layout: config?.layout ?? {width: 'full'},\n }\n}\n","import React, {PropsWithChildren} from 'react'\nimport {Container} from '@sanity/ui'\n\nexport function DashboardLayout(props: PropsWithChildren<{}>) {\n return (\n <Container width={4} padding={4} sizing=\"border\" style={{minHeight: '100%'}}>\n {props.children}\n </Container>\n )\n}\n","import React from 'react'\nimport styled, {css} from 'styled-components'\nimport {Box, Card, Grid, Text} from '@sanity/ui'\nimport {WidgetContainer} from '../containers/WidgetContainer'\nimport {DashboardConfig, LayoutConfig, DashboardWidget} from '../types'\n\nconst media = {\n small: (...args: Parameters<typeof css>) =>\n css`\n @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {\n ${css(...args)}\n }\n `,\n medium: (...args: Parameters<typeof css>) =>\n css`\n @media (min-width: ${({theme}) => theme.sanity.media[2]}px) {\n ${css(...args)}\n }\n `,\n}\n\nconst Root = styled(Grid)`\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n\n & > div {\n overflow: hidden;\n }\n\n & > div[data-width='medium'] {\n ${media.small`\n grid-column: span 2;\n `}\n }\n\n & > div[data-width='large'] {\n ${media.small`\n grid-column: span 2;\n `}\n\n ${media.medium`\n grid-column: span 3;\n `}\n }\n\n & > div[data-width='full'] {\n ${media.small`\n grid-column: 1 / -1;\n `}\n }\n\n & > div[data-height='medium'] {\n ${media.small`\n grid-row: span 2;\n `}\n }\n\n & > div[data-height='large'] {\n ${media.small`\n grid-row: span 2;\n `}\n\n ${media.medium`\n grid-row: span 3;\n `}\n }\n\n & > div[data-height='full'] {\n ${media.medium`\n grid-row: 1 / -1;\n `}\n }\n`\n\nexport interface WidgetGroupProps {\n config: Partial<DashboardConfig>\n}\n\nconst NO_WIDGETS: DashboardWidget[] = []\nconst NO_LAYOUT: LayoutConfig = {}\n\nexport function WidgetGroup(props: WidgetGroupProps) {\n const {\n config: {layout = NO_LAYOUT, widgets = NO_WIDGETS},\n } = props\n return (\n <Root\n autoFlow=\"row dense\"\n data-width={layout.width || 'auto'}\n data-height={layout.height || 'auto'}\n gap={4}\n >\n {widgets.length ? null : (\n <Card padding={4} shadow={1} tone=\"primary\">\n <Text align=\"center\">Add some widgets to populate this space.</Text>\n </Card>\n )}\n {widgets.map((widgetConfig, index) => {\n if (widgetConfig.type === '__experimental_group') {\n return <WidgetGroup key={index} config={widgetConfig} />\n }\n if (widgetConfig.component) {\n return <WidgetContainer key={index} {...widgetConfig} />\n }\n return <Box key={index}>{widgetConfig.name} is missing widget component</Box>\n })}\n </Root>\n )\n}\n","import React from 'react'\nimport {DashboardLayout} from '../components/DashboardLayout'\nimport {WidgetGroup} from '../components/WidgetGroup'\nimport {DashboardContext} from './DashboardContext'\nimport {DashboardConfig} from '../types'\n\nexport function Dashboard({config}: {config: DashboardConfig}) {\n if (!config) {\n return null\n }\n\n return (\n <DashboardContext.Provider value={config}>\n <DashboardLayout>\n <WidgetGroup config={config} />\n </DashboardLayout>\n </DashboardContext.Provider>\n )\n}\n","import React, {CSSProperties} from 'react'\nimport {Dashboard} from './containers/Dashboard'\nimport {definePlugin} from 'sanity'\nimport {DashboardConfig, DashboardWidget, LayoutConfig} from './types'\n\nconst strokeStyle: CSSProperties = {\n stroke: 'currentColor',\n strokeWidth: 1.2,\n}\n\nconst DashboardIcon = () => (\n <svg\n data-sanity-icon\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n preserveAspectRatio=\"xMidYMid\"\n width=\"1em\"\n height=\"1em\"\n >\n <path d=\"M19.5 19.5H5.5V5.5H19.5V19.5Z\" style={strokeStyle} />\n <path d=\"M5.5 12.5H19.5\" style={strokeStyle} />\n <path d=\"M14.5 19.5V12.5M10.5 12.5V5.5\" style={strokeStyle} />\n </svg>\n)\n\nexport interface DashboardPluginConfig {\n widgets?: DashboardWidget[]\n\n /**\n * Will be used for widgets that do not define a layout directly.\n */\n defaultLayout?: LayoutConfig\n}\n\nexport const dashboardTool = definePlugin<DashboardPluginConfig>((config = {}) => {\n const pluginConfig: DashboardConfig = {\n layout: config.defaultLayout ?? {},\n widgets: config.widgets ?? [],\n }\n\n return {\n name: 'dashboard',\n tools: (prev, context) => {\n return [\n ...prev,\n {\n title: 'Dashboard',\n name: 'dashboard',\n icon: DashboardIcon,\n component: () => <Dashboard config={pluginConfig} />,\n },\n ]\n },\n }\n})\n"],"names":["Root","styled","Card","_templateObject","_taggedTemplateLiteral","Header","_templateObject2","Footer","_templateObject3","Content","Box","_templateObject4","_ref","theme","sanity","media","DashboardWidgetContainer","forwardRef","props","ref","header","children","footer","jsxs","radius","display","jsx","borderBottom","paddingX","paddingY","Heading","size","textOverflow","borderTop","useVersionedClient","useClient","apiVersion","DashboardContext","createContext","widgets","WidgetContainer","config","useContext","layout","useMemo","shadow","width","height","createElement","component","getGroqUrl","projectId","dataset","getManageUrl","concat","NO_EXPERIMENTAL","NO_DATA","ProjectInfo","__experimental_before","data","studioHost","setStudioHost","useState","graphqlApi","setGraphQlApi","versionedClient","useEffect","subscriptions","push","observable","request","uri","subscribe","next","result","host","error","console","method","getGraphQlUrl","statusCode","forEach","s","unsubscribe","assembleTableRows","_a","title","rows","value","apps","filter","item","category","a","length","otherStuff","Object","keys","Fragment","map","widgetConfig","idx","_objectSpread","marginTop","Button","style","mode","tone","text","as","href","role","Stack","space","id","padding","Label","muted","row","url","Grid","columns","Text","weight","test","wordBreak","Code","projectInfoWidget","name","AvatarWrapper","_templateObject5","ProjectUsers","project","setProject","users","setUsers","setError","userStore","useUserStore","fetchData","useCallback","subscription","pipe","switchMap","_project","from","getUsers","members","mem","_users","_ref2","Array","isArray","sort","userA","userB","membershipA","find","member","membershipB","isRobot","sortUsersByRobotStatus","e","handleRetryFetch","isLoading","onClick","cursor","loading","align","Spinner","user","membership","RobotIcon","imageUrl","src","alt","displayName","DefaultPreview","subtitle","projectUsersWidget","PlayIconBox","_templateObject6","_ref3","color","card","enabled","bg","Flex","_templateObject7","PosterCard","_templateObject8","Poster","img","_templateObject9","Tutorial","posterURL","showPlayIcon","presenterName","presenterSubtitle","flex","sizing","target","rel","position","direction","marginBottom","PlayIcon","justify","opacity","tutorialsProjectConfig","SanityTutorials","templateRepoId","feedItems","setFeedItems","getFeed","urlBuilder","withCredentials","imageUrlBuilder","useDataAdapter","response","items","overflow","feedItem","index","guideOrTutorial","externalLink","presenter","slug","type","_type","current","paddingRight","paddingLeft","minWidth","hasVideo","poster","image","_id","sanityTutorialsWidget","DashboardLayout","Container","minHeight","css","_templateObject10","_ref4","arguments","_templateObject11","_ref5","_templateObject15","_templateObject18","_templateObject20","NO_WIDGETS","NO_LAYOUT","WidgetGroup","autoFlow","gap","Dashboard","_ref6","Provider","strokeStyle","stroke","strokeWidth","DashboardIcon","viewBox","fill","xmlns","preserveAspectRatio","d","dashboardTool","definePlugin","undefined","_b","pluginConfig","defaultLayout","tools","prev","context","icon"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/components/DashboardWidgetContainer.tsx","../src/versionedClient.ts","../src/containers/DashboardContext.tsx","../src/containers/WidgetContainer.tsx","../src/widgets/projectInfo/ProjectInfo.tsx","../src/widgets/projectInfo/index.ts","../src/widgets/projectUsers/ProjectUsers.tsx","../src/widgets/projectUsers/index.ts","../src/widgets/sanityTutorials/Tutorial.tsx","../src/widgets/sanityTutorials/dataAdapter.ts","../src/widgets/sanityTutorials/SanityTutorials.tsx","../src/widgets/sanityTutorials/index.ts","../src/components/DashboardLayout.tsx","../src/components/WidgetGroup.tsx","../src/containers/Dashboard.tsx","../src/plugin.tsx"],"sourcesContent":["import React, {forwardRef} from 'react'\nimport {Card, Box, Heading} from '@sanity/ui'\nimport styled from 'styled-components'\n\nconst Root = styled(Card)`\n display: flex;\n flex-direction: column;\n justify-content: stretch;\n height: 100%;\n box-sizing: border-box;\n position: relative;\n`\n\nconst Header = styled(Card)`\n position: sticky;\n top: 0;\n z-index: 2;\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n`\n\nconst Footer = styled(Card)`\n position: sticky;\n overflow: hidden;\n bottom: 0;\n z-index: 2;\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n margin-top: auto;\n`\n\nconst Content = styled(Box)`\n position: relative;\n z-index: 1;\n height: stretch;\n min-height: 21.5em;\n\n @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {\n overflow-y: auto;\n outline: none;\n }\n`\n\ninterface DashboardWidgetProps {\n header?: string\n children: React.ReactNode\n footer?: React.ReactNode\n}\n\nexport const DashboardWidgetContainer = forwardRef(function DashboardWidgetContainer(\n props: DashboardWidgetProps,\n ref: React.Ref<HTMLDivElement>\n) {\n const {header, children, footer} = props\n\n return (\n <Root radius={3} display=\"flex\" ref={ref}>\n {header && (\n <Header borderBottom paddingX={3} paddingY={4}>\n <Heading size={1} textOverflow=\"ellipsis\">\n {header}\n </Heading>\n </Header>\n )}\n {children && <Content>{children}</Content>}\n {footer && <Footer borderTop>{footer}</Footer>}\n </Root>\n )\n})\n","import {useClient} from 'sanity'\n\nexport function useVersionedClient() {\n return useClient({apiVersion: '1'})\n}\n","import {createContext, useContext} from 'react'\nimport {DashboardConfig} from '../types'\n\nexport const DashboardContext = createContext<DashboardConfig>({widgets: []})\n\nexport function useDashboardConfig(): DashboardConfig {\n return useContext(DashboardContext)\n}\n","import React, {createElement, useMemo} from 'react'\nimport {useDashboardConfig} from './DashboardContext'\nimport {Card} from '@sanity/ui'\nimport {DashboardWidget} from '../types'\n\nexport function WidgetContainer(props: DashboardWidget) {\n const config = useDashboardConfig()\n const layout = useMemo(\n () => ({\n ...(props.layout || {}),\n ...(config.layout || {}),\n }),\n [props.layout, config.layout]\n )\n\n return (\n <Card shadow={1} data-width={layout.width} data-height={layout.height}>\n {createElement(props.component, {})}\n </Card>\n )\n}\n","import React, {useEffect, useMemo, useState} from 'react'\nimport {Box, Card, Stack, Heading, Grid, Label, Text, Code, Button} from '@sanity/ui'\nimport {useVersionedClient} from '../../versionedClient'\nimport {Subscription} from 'rxjs'\nimport {WidgetContainer} from '../../containers/WidgetContainer'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\nimport {DashboardWidget} from '../../types'\n\nexport interface ProjectInfoProps {\n __experimental_before?: DashboardWidget[]\n data: ProjectData[]\n}\n\ninterface App {\n title: string\n rows?: App[]\n value?: string | {error: string}\n}\n\ninterface ProjectData {\n title: string\n category?: string\n}\n\nfunction isUrl(url?: string) {\n return url && /^https?:\\/\\//.test(`${url}`)\n}\n\nfunction getGraphQlUrl(projectId: string, dataset: string) {\n return `https://${projectId}.api.sanity.io/v1/graphql/${dataset}/default`\n}\n\nfunction getGroqUrl(projectId: string, dataset: string) {\n return `https://${projectId}.api.sanity.io/v1/groq/${dataset}`\n}\n\nfunction getManageUrl(projectId: string) {\n return `https://manage.sanity.io/projects/${projectId}`\n}\n\nconst NO_EXPERIMENTAL: DashboardWidget[] = []\nconst NO_DATA: ProjectData[] = []\n\nexport function ProjectInfo(props: ProjectInfoProps) {\n const {__experimental_before = NO_EXPERIMENTAL, data = NO_DATA} = props\n const [studioHost, setStudioHost] = useState<string | {error: string} | undefined>()\n const [graphqlApi, setGraphQlApi] = useState<string | {error: string} | undefined>()\n const versionedClient = useVersionedClient()\n const {projectId = 'unknown', dataset = 'unknown'} = versionedClient.config()\n\n useEffect(() => {\n const subscriptions: Subscription[] = []\n\n subscriptions.push(\n versionedClient.observable\n .request<{studioHost: string}>({uri: `/projects/${projectId}`})\n .subscribe({\n next: (result) => {\n const {studioHost: host} = result\n setStudioHost(host ? `https://${host}.sanity.studio` : undefined)\n },\n error: (error) => {\n console.error('Error while looking for studioHost', error)\n setStudioHost({\n error: 'Something went wrong while looking up studioHost. See console.',\n })\n },\n })\n )\n\n // ping assumed graphql endpoint\n subscriptions.push(\n versionedClient.observable\n .request({\n method: 'HEAD',\n uri: `/graphql/${dataset}/default`,\n })\n .subscribe({\n next: () => setGraphQlApi(getGraphQlUrl(projectId, dataset)),\n error: (error) => {\n if (error.statusCode === 404) {\n setGraphQlApi(undefined)\n } else {\n console.error('Error while looking for graphqlApi', error)\n setGraphQlApi({\n error: 'Something went wrong while looking up graphqlApi. See console.',\n })\n }\n },\n })\n )\n\n return () => {\n subscriptions.forEach((s) => s.unsubscribe())\n }\n }, [dataset, projectId, versionedClient, setGraphQlApi, setStudioHost])\n\n const assembleTableRows = useMemo(() => {\n let result: App[] = [\n {\n title: 'Sanity project',\n rows: [\n {title: 'Project ID', value: projectId},\n {title: 'Dataset', value: dataset},\n ],\n },\n ]\n\n // Handle any apps\n const apps: App[] = [\n studioHost ? {title: 'Studio', value: studioHost} : null,\n ...data.filter((item) => item.category === 'apps'),\n ].filter((a): a is App => !!a)\n if (apps.length > 0) {\n result = result.concat([{title: 'Apps', rows: apps}])\n }\n\n // Handle APIs\n result = result.concat(\n [\n {\n title: 'APIs',\n rows: [\n {title: 'GROQ', value: getGroqUrl(projectId, dataset)},\n {\n title: 'GraphQL',\n value: (typeof graphqlApi === 'object' ? 'Error' : graphqlApi) ?? 'Not deployed',\n },\n ],\n },\n ],\n data.filter((item) => item.category === 'apis')\n )\n\n // Handle whatever else there might be\n const otherStuff: Record<string, ProjectData[]> = {}\n data.forEach((item) => {\n if (item.category && item.category !== 'apps' && item.category !== 'apis') {\n if (!otherStuff[item.category]) {\n otherStuff[item.category] = []\n }\n otherStuff[item.category].push(item)\n }\n })\n Object.keys(otherStuff).forEach((category) => {\n result.push({title: category, rows: otherStuff[category]})\n })\n\n return result\n }, [graphqlApi, studioHost, projectId, dataset, data])\n\n return (\n <>\n {__experimental_before.map((widgetConfig, idx) => (\n <WidgetContainer key={idx} {...widgetConfig} />\n ))}\n <Box height=\"fill\" marginTop={__experimental_before?.length > 0 ? 4 : 0}>\n <DashboardWidgetContainer\n footer={\n <Button\n style={{width: '100%'}}\n paddingX={2}\n paddingY={4}\n mode=\"bleed\"\n tone=\"primary\"\n text=\"Manage project\"\n as=\"a\"\n href={getManageUrl(projectId)}\n />\n }\n >\n <Card\n paddingY={4}\n radius={2}\n role=\"table\"\n aria-label=\"Project info\"\n aria-describedby=\"project_info_table\"\n >\n <Stack space={4}>\n <Box paddingX={3} as=\"header\">\n <Heading size={1} as=\"h2\" id=\"project_info_table\">\n Project info\n </Heading>\n </Box>\n {assembleTableRows.map((item) => {\n if (!item || !item.rows) {\n return null\n }\n\n return (\n <Stack key={item.title} space={3}>\n <Card borderBottom padding={3}>\n <Label size={0} muted role=\"columnheader\">\n {item.title}\n </Label>\n </Card>\n <Stack space={4} paddingX={3} role=\"rowgroup\">\n {item.rows.map((row) => {\n return (\n <Grid key={row.title} columns={2} role=\"row\">\n <Text weight=\"medium\" role=\"rowheader\">\n {row.title}\n </Text>\n {typeof row.value === 'object' && (\n <Text size={1}>{row.value?.error}</Text>\n )}\n {typeof row.value === 'string' && (\n <>\n {isUrl(row.value) ? (\n <Text size={1} role=\"cell\" style={{wordBreak: 'break-word'}}>\n <a href={row.value}>{row.value}</a>\n </Text>\n ) : (\n <Code size={1} role=\"cell\" style={{wordBreak: 'break-word'}}>\n {row.value}\n </Code>\n )}\n </>\n )}\n </Grid>\n )\n })}\n </Stack>\n </Stack>\n )\n })}\n </Stack>\n </Card>\n </DashboardWidgetContainer>\n </Box>\n </>\n )\n}\n","import {ProjectInfo} from './ProjectInfo'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function projectInfoWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'project-info',\n component: ProjectInfo,\n layout: config?.layout ?? {width: 'medium'},\n }\n}\n","import React, {useCallback, useEffect, useState} from 'react'\nimport {from} from 'rxjs'\nimport {map, switchMap} from 'rxjs/operators'\nimport {Stack, Spinner, Card, Box, Text, Button} from '@sanity/ui'\nimport {RobotIcon} from '@sanity/icons'\nimport styled from 'styled-components'\nimport {DefaultPreview, useUserStore} from 'sanity'\nimport {useVersionedClient} from '../../versionedClient'\nimport {User} from 'sanity'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\n\nconst AvatarWrapper = styled(Card)`\n box-sizing: border-box;\n border-radius: 50%;\n border-color: transparent;\n overflow: hidden;\n width: 100%;\n height: 100%;\n\n & > img {\n width: 100%;\n height: auto;\n }\n`\n\nfunction getInviteUrl(projectId: string) {\n return `https://manage.sanity.io/projects/${projectId}/team/invite`\n}\n\ninterface Member {\n id: string\n role: string\n isRobot: boolean\n}\n\ninterface Project {\n id: string\n members: Member[]\n}\n\nexport function ProjectUsers() {\n const [project, setProject] = useState<Project | undefined>()\n const [users, setUsers] = useState<User[] | undefined>()\n const [error, setError] = useState<Error | undefined>()\n\n const userStore = useUserStore()\n const versionedClient = useVersionedClient()\n\n const fetchData = useCallback(() => {\n const {projectId} = versionedClient.config()\n const subscription = versionedClient.observable\n .request<Project>({\n uri: `/projects/${projectId}`,\n })\n .pipe(\n switchMap((_project) =>\n from(userStore.getUsers(_project.members.map((mem) => mem.id))).pipe(\n map((_users) => ({project: _project, users: _users}))\n )\n )\n )\n .subscribe({\n next: ({users: _users, project: _project}) => {\n setProject(_project)\n setUsers(\n (Array.isArray(_users) ? _users : [_users]).sort((userA, userB) =>\n sortUsersByRobotStatus(userA, userB, _project)\n )\n )\n },\n error: (e: Error) => setError(e),\n })\n\n return () => subscription.unsubscribe()\n }, [userStore, versionedClient])\n\n useEffect(() => fetchData(), [fetchData])\n\n const handleRetryFetch = useCallback(() => fetchData(), [fetchData])\n\n const isLoading = !users || !project\n\n if (error) {\n return (\n <DashboardWidgetContainer header=\"Project users\">\n <Box padding={4}>\n <Text>\n Something went wrong while fetching data. You could{' '}\n <a onClick={handleRetryFetch} title=\"Retry users fetch\" style={{cursor: 'pointer'}}>\n retry\n </a>\n ..?\n </Text>\n </Box>\n </DashboardWidgetContainer>\n )\n }\n\n return (\n <DashboardWidgetContainer\n header=\"Project users\"\n footer={\n <Button\n style={{width: '100%'}}\n paddingX={2}\n paddingY={4}\n mode=\"bleed\"\n tone=\"primary\"\n text=\"Invite members\"\n as=\"a\"\n loading={isLoading}\n href={isLoading ? undefined : getInviteUrl(project.id)}\n />\n }\n >\n {isLoading && (\n <Box paddingY={5} paddingX={2}>\n <Stack space={4}>\n <Text align=\"center\" muted size={1}>\n <Spinner />\n </Text>\n <Text align=\"center\" size={1} muted>\n Loading items...\n </Text>\n </Stack>\n </Box>\n )}\n\n {!isLoading && (\n <Stack space={3} padding={3}>\n {users?.map((user) => {\n const membership = project.members.find((member) => member.id === user.id)\n const media = membership?.isRobot ? (\n <Text size={3}>\n <RobotIcon />\n </Text>\n ) : (\n <AvatarWrapper tone=\"transparent\">\n {user?.imageUrl && <img src={user.imageUrl} alt={user?.displayName} />}\n </AvatarWrapper>\n )\n return (\n <Box key={user.id}>\n <DefaultPreview\n title={user.displayName}\n subtitle={membership?.role}\n media={media}\n />\n </Box>\n )\n })}\n </Stack>\n )}\n </DashboardWidgetContainer>\n )\n}\n\nfunction sortUsersByRobotStatus(userA: User, userB: User, project: Project) {\n const {members} = project\n const membershipA = members.find((member) => member.id === userA?.id)\n const membershipB = members.find((member) => member.id === userB?.id)\n if (membershipA?.isRobot) {\n return 1\n }\n if (membershipB?.isRobot) {\n return -1\n }\n return 0\n}\n","import {ProjectUsers} from './ProjectUsers'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function projectUsersWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'project-info',\n component: ProjectUsers,\n layout: config?.layout,\n }\n}\n","import React from 'react'\nimport {Card, Box, Heading, Flex, Text, Stack} from '@sanity/ui'\nimport {PlayIcon} from '@sanity/icons'\nimport styled from 'styled-components'\n\nconst PlayIconBox = styled(Box)`\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n\n &:before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 2.75em;\n height: 2.75em;\n border-radius: 50%;\n background: ${({theme}) => theme.sanity.color.card.enabled.bg};\n opacity: 0.75;\n }\n`\n\nconst Root = styled(Flex)`\n &:hover {\n ${PlayIconBox} {\n &:before {\n opacity: 1;\n }\n }\n }\n`\n\nconst PosterCard = styled(Card)`\n width: 100%;\n padding-bottom: calc(9 / 16 * 100%);\n position: relative;\n`\n\nconst Poster = styled.img`\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n object-fit: cover;\n display: block;\n\n &:not([src]) {\n display: none;\n }\n`\n\nexport interface TutorialProps {\n title: string\n posterURL?: string\n href: string\n showPlayIcon?: boolean\n presenterName?: string\n presenterSubtitle?: string\n}\n\nexport function Tutorial(props: TutorialProps) {\n const {title, posterURL, showPlayIcon, href, presenterName, presenterSubtitle} = props\n\n return (\n <Root flex={1}>\n <Card\n sizing=\"border\"\n flex={1}\n padding={2}\n radius={2}\n as=\"a\"\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{position: 'relative'}}\n >\n <Flex direction=\"column\" style={{height: '100%'}}>\n {posterURL && (\n <PosterCard marginBottom={1}>\n <Poster src={posterURL} />\n {showPlayIcon && (\n <PlayIconBox display=\"flex\">\n <Text align=\"center\">\n <PlayIcon />\n </Text>\n </PlayIconBox>\n )}\n </PosterCard>\n )}\n <Flex direction=\"column\" justify=\"space-between\" paddingY={2} flex={1}>\n <Heading as=\"h3\" size={1}>\n {title}\n </Heading>\n <Box marginTop={4}>\n <Stack space={2} flex={1}>\n <Text size={1}>{presenterName}</Text>\n <Text size={0} style={{opacity: 0.7}}>\n {presenterSubtitle}\n </Text>\n </Stack>\n </Box>\n </Flex>\n </Flex>\n </Card>\n </Root>\n )\n}\n","import {useMemo} from 'react'\nimport {useVersionedClient} from '../../versionedClient'\nimport imageUrlBuilder from '@sanity/image-url'\n\nconst tutorialsProjectConfig = {\n projectId: '3do82whm',\n dataset: 'next',\n}\n\nexport interface Guide {\n _type?: string\n slug?: {current: string}\n presenter?: {\n name?: string\n }\n}\n\nexport interface FeedItem {\n _id: string\n title?: string\n poster?: string\n category?: string\n guideOrTutorial?: Guide\n externalLink?: string\n presenter?: {\n name?: string\n }\n hasVideo?: boolean\n}\n\nexport function useDataAdapter() {\n const versionedClient = useVersionedClient()\n return useMemo(\n () => ({\n getFeed: (templateRepoId: string) => {\n const uri = templateRepoId\n ? `/addons/dashboard?templateRepoId=${templateRepoId}`\n : '/addons/dashboard'\n return versionedClient.observable.request<{items: FeedItem[]}>({\n uri,\n withCredentials: false,\n })\n },\n urlBuilder: imageUrlBuilder(tutorialsProjectConfig),\n }),\n [versionedClient]\n )\n}\n","import React, {useEffect, useState} from 'react'\nimport {Flex} from '@sanity/ui'\nimport {Tutorial} from './Tutorial'\nimport {FeedItem, Guide, useDataAdapter} from './dataAdapter'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\n\nfunction createUrl(slug: {current: string}, type?: string) {\n if (type === 'tutorial') {\n return `https://www.sanity.io/docs/tutorials/${slug.current}`\n } else if (type === 'guide') {\n return `https://www.sanity.io/docs/guides/${slug.current}`\n }\n return false\n}\n\nexport interface SanityTutorialsProps {\n templateRepoId: string\n}\n\nexport function SanityTutorials(props: SanityTutorialsProps) {\n const {templateRepoId} = props\n const [feedItems, setFeedItems] = useState<FeedItem[]>([])\n\n const {getFeed, urlBuilder} = useDataAdapter()\n\n useEffect(() => {\n const subscription = getFeed(templateRepoId).subscribe((response) => {\n setFeedItems(response.items)\n })\n return () => {\n subscription.unsubscribe()\n }\n }, [setFeedItems, getFeed, templateRepoId])\n\n const title = 'Learn about Sanity'\n\n return (\n <DashboardWidgetContainer header={title}>\n <Flex as=\"ul\" overflow=\"auto\" align=\"stretch\" paddingY={2}>\n {feedItems?.map((feedItem, index) => {\n if (!feedItem.title || (!feedItem.guideOrTutorial && !feedItem.externalLink)) {\n return null\n }\n const presenter = feedItem.presenter || feedItem.guideOrTutorial?.presenter || {}\n const subtitle = feedItem.category\n const {guideOrTutorial = {} as Guide} = feedItem\n const href =\n (guideOrTutorial.slug\n ? createUrl(guideOrTutorial.slug, guideOrTutorial._type)\n : feedItem.externalLink) || feedItem.externalLink\n\n return (\n <Flex\n as=\"li\"\n key={feedItem._id}\n paddingRight={index < feedItems?.length - 1 ? 1 : 3}\n paddingLeft={index === 0 ? 3 : 0}\n align=\"stretch\"\n style={{minWidth: 272, width: '30%'}}\n >\n <Tutorial\n title={feedItem.title}\n href={href ?? ''}\n presenterName={presenter.name}\n presenterSubtitle={subtitle}\n showPlayIcon={feedItem.hasVideo}\n posterURL={\n feedItem.poster ? urlBuilder.image(feedItem.poster).height(360).url() : undefined\n }\n />\n </Flex>\n )\n })}\n </Flex>\n </DashboardWidgetContainer>\n )\n}\n","import {SanityTutorials} from './SanityTutorials'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function sanityTutorialsWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'sanity-tutorials',\n component: SanityTutorials,\n layout: config?.layout ?? {width: 'full'},\n }\n}\n","import React, {PropsWithChildren} from 'react'\nimport {Container} from '@sanity/ui'\n\nexport function DashboardLayout(props: PropsWithChildren<{}>) {\n return (\n <Container width={4} padding={4} sizing=\"border\" style={{height: '100%', overflowY: 'auto'}}>\n {props.children}\n </Container>\n )\n}\n","import React from 'react'\nimport styled, {css} from 'styled-components'\nimport {Box, Card, Grid, Text} from '@sanity/ui'\nimport {WidgetContainer} from '../containers/WidgetContainer'\nimport {DashboardConfig, LayoutConfig, DashboardWidget} from '../types'\n\nconst media = {\n small: (...args: Parameters<typeof css>) =>\n css`\n @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {\n ${css(...args)}\n }\n `,\n medium: (...args: Parameters<typeof css>) =>\n css`\n @media (min-width: ${({theme}) => theme.sanity.media[2]}px) {\n ${css(...args)}\n }\n `,\n}\n\nconst Root = styled(Grid)`\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n\n & > div {\n overflow: hidden;\n }\n\n & > div[data-width='medium'] {\n ${media.small`\n grid-column: span 2;\n `}\n }\n\n & > div[data-width='large'] {\n ${media.small`\n grid-column: span 2;\n `}\n\n ${media.medium`\n grid-column: span 3;\n `}\n }\n\n & > div[data-width='full'] {\n ${media.small`\n grid-column: 1 / -1;\n `}\n }\n\n & > div[data-height='medium'] {\n ${media.small`\n grid-row: span 2;\n `}\n }\n\n & > div[data-height='large'] {\n ${media.small`\n grid-row: span 2;\n `}\n\n ${media.medium`\n grid-row: span 3;\n `}\n }\n\n & > div[data-height='full'] {\n ${media.medium`\n grid-row: 1 / -1;\n `}\n }\n`\n\nexport interface WidgetGroupProps {\n config: Partial<DashboardConfig>\n}\n\nconst NO_WIDGETS: DashboardWidget[] = []\nconst NO_LAYOUT: LayoutConfig = {}\n\nexport function WidgetGroup(props: WidgetGroupProps) {\n const {\n config: {layout = NO_LAYOUT, widgets = NO_WIDGETS},\n } = props\n return (\n <Root\n autoFlow=\"row dense\"\n data-width={layout.width || 'auto'}\n data-height={layout.height || 'auto'}\n gap={4}\n >\n {widgets.length ? null : (\n <Card padding={4} shadow={1} tone=\"primary\">\n <Text align=\"center\">Add some widgets to populate this space.</Text>\n </Card>\n )}\n {widgets.map((widgetConfig, index) => {\n if (widgetConfig.type === '__experimental_group') {\n return <WidgetGroup key={index} config={widgetConfig} />\n }\n if (widgetConfig.component) {\n return <WidgetContainer key={index} {...widgetConfig} />\n }\n return <Box key={index}>{widgetConfig.name} is missing widget component</Box>\n })}\n </Root>\n )\n}\n","import React from 'react'\nimport {DashboardLayout} from '../components/DashboardLayout'\nimport {WidgetGroup} from '../components/WidgetGroup'\nimport {DashboardContext} from './DashboardContext'\nimport {DashboardConfig} from '../types'\n\nexport function Dashboard({config}: {config: DashboardConfig}) {\n if (!config) {\n return null\n }\n\n return (\n <DashboardContext.Provider value={config}>\n <DashboardLayout>\n <WidgetGroup config={config} />\n </DashboardLayout>\n </DashboardContext.Provider>\n )\n}\n","import React, {ComponentType, CSSProperties} from 'react'\nimport {Dashboard} from './containers/Dashboard'\nimport {definePlugin} from 'sanity'\nimport {DashboardConfig, DashboardWidget, LayoutConfig} from './types'\n\nconst strokeStyle: CSSProperties = {\n stroke: 'currentColor',\n strokeWidth: 1.2,\n}\n\nconst DashboardIcon = () => (\n <svg\n data-sanity-icon\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n preserveAspectRatio=\"xMidYMid\"\n width=\"1em\"\n height=\"1em\"\n >\n <path d=\"M19.5 19.5H5.5V5.5H19.5V19.5Z\" style={strokeStyle} />\n <path d=\"M5.5 12.5H19.5\" style={strokeStyle} />\n <path d=\"M14.5 19.5V12.5M10.5 12.5V5.5\" style={strokeStyle} />\n </svg>\n)\n\nexport interface DashboardPluginConfig {\n /**\n * Dashboard tool title\n */\n title?: string\n /**\n * Dashboard tool name (used in url path)\n */\n name?: string\n /**\n * Dashboard tool icon\n */\n icon?: ComponentType\n widgets?: DashboardWidget[]\n\n /**\n * Will be used for widgets that do not define a layout directly.\n */\n defaultLayout?: LayoutConfig\n}\n\nexport const dashboardTool = definePlugin<DashboardPluginConfig>((config = {}) => {\n const pluginConfig: DashboardConfig = {\n layout: config.defaultLayout ?? {},\n widgets: config.widgets ?? [],\n }\n\n const title = config.title ?? 'Dashboard'\n const name = config.name ?? 'dashboard'\n const icon = config.icon ?? DashboardIcon\n\n return {\n name: 'dashboard',\n tools: (prev, context) => {\n return [\n ...prev,\n {\n title,\n name,\n icon,\n component: () => <Dashboard config={pluginConfig} />,\n },\n ]\n },\n }\n})\n"],"names":["Root","styled","Card","_templateObject","_taggedTemplateLiteral","Header","_templateObject2","Footer","_templateObject3","Content","Box","_templateObject4","_ref","theme","sanity","media","DashboardWidgetContainer","forwardRef","props","ref","header","children","footer","jsxs","radius","display","jsx","borderBottom","paddingX","paddingY","Heading","size","textOverflow","borderTop","useVersionedClient","useClient","apiVersion","DashboardContext","createContext","widgets","WidgetContainer","config","useContext","layout","useMemo","shadow","width","height","createElement","component","getGroqUrl","projectId","dataset","getManageUrl","concat","NO_EXPERIMENTAL","NO_DATA","ProjectInfo","__experimental_before","data","studioHost","setStudioHost","useState","graphqlApi","setGraphQlApi","versionedClient","useEffect","subscriptions","push","observable","request","uri","subscribe","next","result","host","error","console","method","getGraphQlUrl","statusCode","forEach","s","unsubscribe","assembleTableRows","_a","title","rows","value","apps","filter","item","category","a","length","otherStuff","Object","keys","Fragment","map","widgetConfig","idx","_objectSpread","marginTop","Button","style","mode","tone","text","as","href","role","Stack","space","id","padding","Label","muted","row","url","Grid","columns","Text","weight","test","wordBreak","Code","projectInfoWidget","name","AvatarWrapper","_templateObject5","ProjectUsers","project","setProject","users","setUsers","setError","userStore","useUserStore","fetchData","useCallback","subscription","pipe","switchMap","_project","from","getUsers","members","mem","_users","_ref2","Array","isArray","sort","userA","userB","membershipA","find","member","membershipB","isRobot","sortUsersByRobotStatus","e","handleRetryFetch","isLoading","onClick","cursor","loading","align","Spinner","user","membership","RobotIcon","imageUrl","src","alt","displayName","DefaultPreview","subtitle","projectUsersWidget","PlayIconBox","_templateObject6","_ref3","color","card","enabled","bg","Flex","_templateObject7","PosterCard","_templateObject8","Poster","img","_templateObject9","Tutorial","posterURL","showPlayIcon","presenterName","presenterSubtitle","flex","sizing","target","rel","position","direction","marginBottom","PlayIcon","justify","opacity","tutorialsProjectConfig","SanityTutorials","templateRepoId","feedItems","setFeedItems","getFeed","urlBuilder","withCredentials","imageUrlBuilder","useDataAdapter","response","items","overflow","feedItem","index","guideOrTutorial","externalLink","presenter","slug","type","_type","current","paddingRight","paddingLeft","minWidth","hasVideo","poster","image","_id","sanityTutorialsWidget","DashboardLayout","Container","overflowY","css","_templateObject10","_ref4","arguments","_templateObject11","_ref5","_templateObject15","_templateObject18","_templateObject20","NO_WIDGETS","NO_LAYOUT","WidgetGroup","autoFlow","gap","Dashboard","_ref6","Provider","strokeStyle","stroke","strokeWidth","DashboardIcon","viewBox","fill","xmlns","preserveAspectRatio","d","dashboardTool","definePlugin","undefined","_b","_c","_d","_e","pluginConfig","defaultLayout","icon","tools","prev","context"],"mappings":"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"}
package/lib/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var e,t,n,r,i,o,s,a,l,d,c,u,h,p,g,f,x,m,j,b;function y(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function w(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?y(Object(n),!0).forEach((function(t){v(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):y(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function v(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function k(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}Object.defineProperty(exports,"__esModule",{value:!0});var O=require("react/jsx-runtime"),S=require("react"),P=require("@sanity/ui"),C=require("styled-components"),z=require("sanity"),B=require("rxjs"),T=require("rxjs/operators"),q=require("@sanity/icons"),_=require("@sanity/image-url");function E(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var I=E(C),R=E(_);const M=I.default(P.Card)(e||(e=k(["\n display: flex;\n flex-direction: column;\n justify-content: stretch;\n height: 100%;\n box-sizing: border-box;\n position: relative;\n"]))),H=I.default(P.Card)(t||(t=k(["\n position: sticky;\n top: 0;\n z-index: 2;\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n"]))),L=I.default(P.Card)(n||(n=k(["\n position: sticky;\n overflow: hidden;\n bottom: 0;\n z-index: 2;\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n margin-top: auto;\n"]))),D=I.default(P.Box)(r||(r=k(["\n position: relative;\n z-index: 1;\n height: stretch;\n min-height: 21.5em;\n\n @media (min-width: ","px) {\n overflow-y: auto;\n outline: none;\n }\n"])),(e=>{let{theme:t}=e;return t.sanity.media[0]})),F=S.forwardRef((function(e,t){const{header:n,children:r,footer:i}=e;return O.jsxs(M,{radius:3,display:"flex",ref:t,children:[n&&O.jsx(H,{borderBottom:!0,paddingX:3,paddingY:4,children:O.jsx(P.Heading,{size:1,textOverflow:"ellipsis",children:n})}),r&&O.jsx(D,{children:r}),i&&O.jsx(L,{borderTop:!0,children:i})]})}));function A(){return z.useClient({apiVersion:"1"})}const Y=S.createContext({widgets:[]});function U(e){const t=S.useContext(Y),n=S.useMemo((()=>w(w({},e.layout||{}),t.layout||{})),[e.layout,t.layout]);return O.jsx(P.Card,{shadow:1,"data-width":n.width,"data-height":n.height,children:S.createElement(e.component,{})})}function V(e,t){return"https://".concat(e,".api.sanity.io/v1/groq/").concat(t)}function W(e){return"https://manage.sanity.io/projects/".concat(e)}const X=[],N=[];function G(e){const{__experimental_before:t=X,data:n=N}=e,[r,i]=S.useState(),[o,s]=S.useState(),a=A(),{projectId:l="unknown",dataset:d="unknown"}=a.config();S.useEffect((()=>{const e=[];return e.push(a.observable.request({uri:"/projects/".concat(l)}).subscribe({next:e=>{const{studioHost:t}=e;i(t?"https://".concat(t,".sanity.studio"):void 0)},error:e=>{console.error("Error while looking for studioHost",e),i({error:"Something went wrong while looking up studioHost. See console."})}})),e.push(a.observable.request({method:"HEAD",uri:"/graphql/".concat(d,"/default")}).subscribe({next:()=>s(function(e,t){return"https://".concat(e,".api.sanity.io/v1/graphql/").concat(t,"/default")}(l,d)),error:e=>{404===e.statusCode?s(void 0):(console.error("Error while looking for graphqlApi",e),s({error:"Something went wrong while looking up graphqlApi. See console."}))}})),()=>{e.forEach((e=>e.unsubscribe()))}}),[d,l,a,s,i]);const c=S.useMemo((()=>{var e;let t=[{title:"Sanity project",rows:[{title:"Project ID",value:l},{title:"Dataset",value:d}]}];const i=[r?{title:"Studio",value:r}:null,...n.filter((e=>"apps"===e.category))].filter((e=>!!e));i.length>0&&(t=t.concat([{title:"Apps",rows:i}])),t=t.concat([{title:"APIs",rows:[{title:"GROQ",value:V(l,d)},{title:"GraphQL",value:null!=(e="object"==typeof o?"Error":o)?e:"Not deployed"}]}],n.filter((e=>"apis"===e.category)));const s={};return n.forEach((e=>{e.category&&"apps"!==e.category&&"apis"!==e.category&&(s[e.category]||(s[e.category]=[]),s[e.category].push(e))})),Object.keys(s).forEach((e=>{t.push({title:e,rows:s[e]})})),t}),[o,r,l,d,n]);return O.jsxs(O.Fragment,{children:[t.map(((e,t)=>O.jsx(U,w({},e),t))),O.jsx(P.Box,{height:"fill",marginTop:(null==t?void 0:t.length)>0?4:0,children:O.jsx(F,{footer:O.jsx(P.Button,{style:{width:"100%"},paddingX:2,paddingY:4,mode:"bleed",tone:"primary",text:"Manage project",as:"a",href:W(l)}),children:O.jsx(P.Card,{paddingY:4,radius:2,role:"table","aria-label":"Project info","aria-describedby":"project_info_table",children:O.jsxs(P.Stack,{space:4,children:[O.jsx(P.Box,{paddingX:3,as:"header",children:O.jsx(P.Heading,{size:1,as:"h2",id:"project_info_table",children:"Project info"})}),c.map((e=>e&&e.rows?O.jsxs(P.Stack,{space:3,children:[O.jsx(P.Card,{borderBottom:!0,padding:3,children:O.jsx(P.Label,{size:0,muted:!0,role:"columnheader",children:e.title})}),O.jsx(P.Stack,{space:4,paddingX:3,role:"rowgroup",children:e.rows.map((e=>{var t,n;return O.jsxs(P.Grid,{columns:2,role:"row",children:[O.jsx(P.Text,{weight:"medium",role:"rowheader",children:e.title}),"object"==typeof e.value&&O.jsx(P.Text,{size:1,children:null==(t=e.value)?void 0:t.error}),"string"==typeof e.value&&O.jsx(O.Fragment,{children:(n=e.value,n&&/^https?:\/\//.test("".concat(n))?O.jsx(P.Text,{size:1,role:"cell",style:{wordBreak:"break-word"},children:O.jsx("a",{href:e.value,children:e.value})}):O.jsx(P.Code,{size:1,role:"cell",style:{wordBreak:"break-word"},children:e.value}))})]},e.title)}))})]},e.title):null))]})})})})]})}const Q=I.default(P.Card)(i||(i=k(["\n box-sizing: border-box;\n border-radius: 50%;\n border-color: transparent;\n overflow: hidden;\n width: 100%;\n height: 100%;\n\n & > img {\n width: 100%;\n height: auto;\n }\n"])));function Z(){const[e,t]=S.useState(),[n,r]=S.useState(),[i,o]=S.useState(),s=z.useUserStore(),a=A(),l=S.useCallback((()=>{const{projectId:e}=a.config(),n=a.observable.request({uri:"/projects/".concat(e)}).pipe(T.switchMap((e=>B.from(s.getUsers(e.members.map((e=>e.id)))).pipe(T.map((t=>({project:e,users:t}))))))).subscribe({next:e=>{let{users:n,project:i}=e;t(i),r((Array.isArray(n)?n:[n]).sort(((e,t)=>function(e,t,n){const{members:r}=n,i=r.find((t=>t.id===(null==e?void 0:e.id))),o=r.find((e=>e.id===(null==t?void 0:t.id)));if(null==i?void 0:i.isRobot)return 1;if(null==o?void 0:o.isRobot)return-1;return 0}(e,t,i))))},error:e=>o(e)});return()=>n.unsubscribe()}),[s,a]);S.useEffect((()=>l()),[l]);const d=S.useCallback((()=>l()),[l]),c=!n||!e;return i?O.jsx(F,{header:"Project users",children:O.jsx(P.Box,{padding:4,children:O.jsxs(P.Text,{children:["Something went wrong while fetching data. You could"," ",O.jsx("a",{onClick:d,title:"Retry users fetch",style:{cursor:"pointer"},children:"retry"}),"..?"]})})}):O.jsxs(F,{header:"Project users",footer:O.jsx(P.Button,{style:{width:"100%"},paddingX:2,paddingY:4,mode:"bleed",tone:"primary",text:"Invite members",as:"a",loading:c,href:c?void 0:(u=e.id,"https://manage.sanity.io/projects/".concat(u,"/team/invite"))}),children:[c&&O.jsx(P.Box,{paddingY:5,paddingX:2,children:O.jsxs(P.Stack,{space:4,children:[O.jsx(P.Text,{align:"center",muted:!0,size:1,children:O.jsx(P.Spinner,{})}),O.jsx(P.Text,{align:"center",size:1,muted:!0,children:"Loading items..."})]})}),!c&&O.jsx(P.Stack,{space:3,padding:3,children:null==n?void 0:n.map((t=>{const n=e.members.find((e=>e.id===t.id)),r=(null==n?void 0:n.isRobot)?O.jsx(P.Text,{size:3,children:O.jsx(q.RobotIcon,{})}):O.jsx(Q,{tone:"transparent",children:(null==t?void 0:t.imageUrl)&&O.jsx("img",{src:t.imageUrl,alt:null==t?void 0:t.displayName})});return O.jsx(P.Box,{children:O.jsx(z.DefaultPreview,{title:t.displayName,subtitle:null==n?void 0:n.role,media:r})},t.id)}))})]});var u}const J=I.default(P.Box)(o||(o=k(["\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n\n &:before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 2.75em;\n height: 2.75em;\n border-radius: 50%;\n background: ",";\n opacity: 0.75;\n }\n"])),(e=>{let{theme:t}=e;return t.sanity.color.card.enabled.bg})),K=I.default(P.Flex)(s||(s=k(["\n &:hover {\n "," {\n &:before {\n opacity: 1;\n }\n }\n }\n"])),J),$=I.default(P.Card)(a||(a=k(["\n width: 100%;\n padding-bottom: calc(9 / 16 * 100%);\n position: relative;\n"]))),ee=I.default.img(l||(l=k(["\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n object-fit: cover;\n display: block;\n\n &:not([src]) {\n display: none;\n }\n"])));function te(e){const{title:t,posterURL:n,showPlayIcon:r,href:i,presenterName:o,presenterSubtitle:s}=e;return O.jsx(K,{flex:1,children:O.jsx(P.Card,{sizing:"border",flex:1,padding:2,radius:2,as:"a",href:i,target:"_blank",rel:"noopener noreferrer",style:{position:"relative"},children:O.jsxs(P.Flex,{direction:"column",style:{height:"100%"},children:[n&&O.jsxs($,{marginBottom:1,children:[O.jsx(ee,{src:n}),r&&O.jsx(J,{display:"flex",children:O.jsx(P.Text,{align:"center",children:O.jsx(q.PlayIcon,{})})})]}),O.jsxs(P.Flex,{direction:"column",justify:"space-between",paddingY:2,flex:1,children:[O.jsx(P.Heading,{as:"h3",size:1,children:t}),O.jsx(P.Box,{marginTop:4,children:O.jsxs(P.Stack,{space:2,flex:1,children:[O.jsx(P.Text,{size:1,children:o}),O.jsx(P.Text,{size:0,style:{opacity:.7},children:s})]})})]})]})})})}const ne={projectId:"3do82whm",dataset:"next"};function re(e){const{templateRepoId:t}=e,[n,r]=S.useState([]),{getFeed:i,urlBuilder:o}=function(){const e=A();return S.useMemo((()=>({getFeed:t=>{const n=t?"/addons/dashboard?templateRepoId=".concat(t):"/addons/dashboard";return e.observable.request({uri:n,withCredentials:!1})},urlBuilder:R.default(ne)})),[e])}();S.useEffect((()=>{const e=i(t).subscribe((e=>{r(e.items)}));return()=>{e.unsubscribe()}}),[r,i,t]);return O.jsx(F,{header:"Learn about Sanity",children:O.jsx(P.Flex,{as:"ul",overflow:"auto",align:"stretch",paddingY:2,children:null==n?void 0:n.map(((e,t)=>{var r;if(!e.title||!e.guideOrTutorial&&!e.externalLink)return null;const i=e.presenter||(null==(r=e.guideOrTutorial)?void 0:r.presenter)||{},s=e.category,{guideOrTutorial:a={}}=e,l=(a.slug?(d=a.slug,"tutorial"===(c=a._type)?"https://www.sanity.io/docs/tutorials/".concat(d.current):"guide"===c&&"https://www.sanity.io/docs/guides/".concat(d.current)):e.externalLink)||e.externalLink;var d,c;return O.jsx(P.Flex,{as:"li",paddingRight:t<(null==n?void 0:n.length)-1?1:3,paddingLeft:0===t?3:0,align:"stretch",style:{minWidth:272,width:"30%"},children:O.jsx(te,{title:e.title,href:null!=l?l:"",presenterName:i.name,presenterSubtitle:s,showPlayIcon:e.hasVideo,posterURL:e.poster?o.image(e.poster).height(360).url():void 0})},e._id)}))})})}function ie(e){return O.jsx(P.Container,{width:4,padding:4,sizing:"border",style:{minHeight:"100%"},children:e.children})}const oe=function(){return C.css(d||(d=k(["\n @media (min-width: ","px) {\n ","\n }\n "])),(e=>{let{theme:t}=e;return t.sanity.media[0]}),C.css(...arguments))},se=function(){return C.css(c||(c=k(["\n @media (min-width: ","px) {\n ","\n }\n "])),(e=>{let{theme:t}=e;return t.sanity.media[2]}),C.css(...arguments))},ae=I.default(P.Grid)(u||(u=k(["\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n\n & > div {\n overflow: hidden;\n }\n\n & > div[data-width='medium'] {\n ","\n }\n\n & > div[data-width='large'] {\n ","\n\n ","\n }\n\n & > div[data-width='full'] {\n ","\n }\n\n & > div[data-height='medium'] {\n ","\n }\n\n & > div[data-height='large'] {\n ","\n\n ","\n }\n\n & > div[data-height='full'] {\n ","\n }\n"])),oe(h||(h=k(["\n grid-column: span 2;\n "]))),oe(p||(p=k(["\n grid-column: span 2;\n "]))),se(g||(g=k(["\n grid-column: span 3;\n "]))),oe(f||(f=k(["\n grid-column: 1 / -1;\n "]))),oe(x||(x=k(["\n grid-row: span 2;\n "]))),oe(m||(m=k(["\n grid-row: span 2;\n "]))),se(j||(j=k(["\n grid-row: span 3;\n "]))),se(b||(b=k(["\n grid-row: 1 / -1;\n "])))),le=[],de={};function ce(e){const{config:{layout:t=de,widgets:n=le}}=e;return O.jsxs(ae,{autoFlow:"row dense","data-width":t.width||"auto","data-height":t.height||"auto",gap:4,children:[n.length?null:O.jsx(P.Card,{padding:4,shadow:1,tone:"primary",children:O.jsx(P.Text,{align:"center",children:"Add some widgets to populate this space."})}),n.map(((e,t)=>"__experimental_group"===e.type?O.jsx(ce,{config:e},t):e.component?O.jsx(U,w({},e),t):O.jsxs(P.Box,{children:[e.name," is missing widget component"]},t)))]})}function ue(e){let{config:t}=e;return t?O.jsx(Y.Provider,{value:t,children:O.jsx(ie,{children:O.jsx(ce,{config:t})})}):null}const he={stroke:"currentColor",strokeWidth:1.2},pe=()=>O.jsxs("svg",{"data-sanity-icon":!0,viewBox:"0 0 25 25",fill:"none",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid",width:"1em",height:"1em",children:[O.jsx("path",{d:"M19.5 19.5H5.5V5.5H19.5V19.5Z",style:he}),O.jsx("path",{d:"M5.5 12.5H19.5",style:he}),O.jsx("path",{d:"M14.5 19.5V12.5M10.5 12.5V5.5",style:he})]}),ge=z.definePlugin((function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};var t,n;const r={layout:null!=(t=e.defaultLayout)?t:{},widgets:null!=(n=e.widgets)?n:[]};return{name:"dashboard",tools:(e,t)=>[...e,{title:"Dashboard",name:"dashboard",icon:pe,component:()=>O.jsx(ue,{config:r})}]}}));exports.DashboardWidgetContainer=F,exports.dashboardTool=ge,exports.projectInfoWidget=function(e){var t;return{name:"project-info",component:G,layout:null!=(t=null==e?void 0:e.layout)?t:{width:"medium"}}},exports.projectUsersWidget=function(e){return{name:"project-info",component:Z,layout:null==e?void 0:e.layout}},exports.sanityTutorialsWidget=function(e){var t;return{name:"sanity-tutorials",component:re,layout:null!=(t=null==e?void 0:e.layout)?t:{width:"full"}}};
1
+ "use strict";var e,t,n,r,i,o,s,a,l,d,c,u,h,p,g,f,x,m,j,b;function y(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function w(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?y(Object(n),!0).forEach((function(t){v(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):y(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function v(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function k(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}Object.defineProperty(exports,"__esModule",{value:!0});var O=require("react/jsx-runtime"),S=require("react"),P=require("@sanity/ui"),C=require("styled-components"),z=require("sanity"),B=require("rxjs"),T=require("rxjs/operators"),q=require("@sanity/icons"),_=require("@sanity/image-url");function E(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var I=E(C),R=E(_);const M=I.default(P.Card)(e||(e=k(["\n display: flex;\n flex-direction: column;\n justify-content: stretch;\n height: 100%;\n box-sizing: border-box;\n position: relative;\n"]))),L=I.default(P.Card)(t||(t=k(["\n position: sticky;\n top: 0;\n z-index: 2;\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n"]))),D=I.default(P.Card)(n||(n=k(["\n position: sticky;\n overflow: hidden;\n bottom: 0;\n z-index: 2;\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n margin-top: auto;\n"]))),F=I.default(P.Box)(r||(r=k(["\n position: relative;\n z-index: 1;\n height: stretch;\n min-height: 21.5em;\n\n @media (min-width: ","px) {\n overflow-y: auto;\n outline: none;\n }\n"])),(e=>{let{theme:t}=e;return t.sanity.media[0]})),H=S.forwardRef((function(e,t){const{header:n,children:r,footer:i}=e;return O.jsxs(M,{radius:3,display:"flex",ref:t,children:[n&&O.jsx(L,{borderBottom:!0,paddingX:3,paddingY:4,children:O.jsx(P.Heading,{size:1,textOverflow:"ellipsis",children:n})}),r&&O.jsx(F,{children:r}),i&&O.jsx(D,{borderTop:!0,children:i})]})}));function Y(){return z.useClient({apiVersion:"1"})}const A=S.createContext({widgets:[]});function U(e){const t=S.useContext(A),n=S.useMemo((()=>w(w({},e.layout||{}),t.layout||{})),[e.layout,t.layout]);return O.jsx(P.Card,{shadow:1,"data-width":n.width,"data-height":n.height,children:S.createElement(e.component,{})})}function V(e,t){return"https://".concat(e,".api.sanity.io/v1/groq/").concat(t)}function W(e){return"https://manage.sanity.io/projects/".concat(e)}const X=[],N=[];function G(e){const{__experimental_before:t=X,data:n=N}=e,[r,i]=S.useState(),[o,s]=S.useState(),a=Y(),{projectId:l="unknown",dataset:d="unknown"}=a.config();S.useEffect((()=>{const e=[];return e.push(a.observable.request({uri:"/projects/".concat(l)}).subscribe({next:e=>{const{studioHost:t}=e;i(t?"https://".concat(t,".sanity.studio"):void 0)},error:e=>{console.error("Error while looking for studioHost",e),i({error:"Something went wrong while looking up studioHost. See console."})}})),e.push(a.observable.request({method:"HEAD",uri:"/graphql/".concat(d,"/default")}).subscribe({next:()=>s(function(e,t){return"https://".concat(e,".api.sanity.io/v1/graphql/").concat(t,"/default")}(l,d)),error:e=>{404===e.statusCode?s(void 0):(console.error("Error while looking for graphqlApi",e),s({error:"Something went wrong while looking up graphqlApi. See console."}))}})),()=>{e.forEach((e=>e.unsubscribe()))}}),[d,l,a,s,i]);const c=S.useMemo((()=>{var e;let t=[{title:"Sanity project",rows:[{title:"Project ID",value:l},{title:"Dataset",value:d}]}];const i=[r?{title:"Studio",value:r}:null,...n.filter((e=>"apps"===e.category))].filter((e=>!!e));i.length>0&&(t=t.concat([{title:"Apps",rows:i}])),t=t.concat([{title:"APIs",rows:[{title:"GROQ",value:V(l,d)},{title:"GraphQL",value:null!=(e="object"==typeof o?"Error":o)?e:"Not deployed"}]}],n.filter((e=>"apis"===e.category)));const s={};return n.forEach((e=>{e.category&&"apps"!==e.category&&"apis"!==e.category&&(s[e.category]||(s[e.category]=[]),s[e.category].push(e))})),Object.keys(s).forEach((e=>{t.push({title:e,rows:s[e]})})),t}),[o,r,l,d,n]);return O.jsxs(O.Fragment,{children:[t.map(((e,t)=>O.jsx(U,w({},e),t))),O.jsx(P.Box,{height:"fill",marginTop:(null==t?void 0:t.length)>0?4:0,children:O.jsx(H,{footer:O.jsx(P.Button,{style:{width:"100%"},paddingX:2,paddingY:4,mode:"bleed",tone:"primary",text:"Manage project",as:"a",href:W(l)}),children:O.jsx(P.Card,{paddingY:4,radius:2,role:"table","aria-label":"Project info","aria-describedby":"project_info_table",children:O.jsxs(P.Stack,{space:4,children:[O.jsx(P.Box,{paddingX:3,as:"header",children:O.jsx(P.Heading,{size:1,as:"h2",id:"project_info_table",children:"Project info"})}),c.map((e=>e&&e.rows?O.jsxs(P.Stack,{space:3,children:[O.jsx(P.Card,{borderBottom:!0,padding:3,children:O.jsx(P.Label,{size:0,muted:!0,role:"columnheader",children:e.title})}),O.jsx(P.Stack,{space:4,paddingX:3,role:"rowgroup",children:e.rows.map((e=>{var t,n;return O.jsxs(P.Grid,{columns:2,role:"row",children:[O.jsx(P.Text,{weight:"medium",role:"rowheader",children:e.title}),"object"==typeof e.value&&O.jsx(P.Text,{size:1,children:null==(t=e.value)?void 0:t.error}),"string"==typeof e.value&&O.jsx(O.Fragment,{children:(n=e.value,n&&/^https?:\/\//.test("".concat(n))?O.jsx(P.Text,{size:1,role:"cell",style:{wordBreak:"break-word"},children:O.jsx("a",{href:e.value,children:e.value})}):O.jsx(P.Code,{size:1,role:"cell",style:{wordBreak:"break-word"},children:e.value}))})]},e.title)}))})]},e.title):null))]})})})})]})}const Q=I.default(P.Card)(i||(i=k(["\n box-sizing: border-box;\n border-radius: 50%;\n border-color: transparent;\n overflow: hidden;\n width: 100%;\n height: 100%;\n\n & > img {\n width: 100%;\n height: auto;\n }\n"])));function Z(){const[e,t]=S.useState(),[n,r]=S.useState(),[i,o]=S.useState(),s=z.useUserStore(),a=Y(),l=S.useCallback((()=>{const{projectId:e}=a.config(),n=a.observable.request({uri:"/projects/".concat(e)}).pipe(T.switchMap((e=>B.from(s.getUsers(e.members.map((e=>e.id)))).pipe(T.map((t=>({project:e,users:t}))))))).subscribe({next:e=>{let{users:n,project:i}=e;t(i),r((Array.isArray(n)?n:[n]).sort(((e,t)=>function(e,t,n){const{members:r}=n,i=r.find((t=>t.id===(null==e?void 0:e.id))),o=r.find((e=>e.id===(null==t?void 0:t.id)));if(null==i?void 0:i.isRobot)return 1;if(null==o?void 0:o.isRobot)return-1;return 0}(e,t,i))))},error:e=>o(e)});return()=>n.unsubscribe()}),[s,a]);S.useEffect((()=>l()),[l]);const d=S.useCallback((()=>l()),[l]),c=!n||!e;return i?O.jsx(H,{header:"Project users",children:O.jsx(P.Box,{padding:4,children:O.jsxs(P.Text,{children:["Something went wrong while fetching data. You could"," ",O.jsx("a",{onClick:d,title:"Retry users fetch",style:{cursor:"pointer"},children:"retry"}),"..?"]})})}):O.jsxs(H,{header:"Project users",footer:O.jsx(P.Button,{style:{width:"100%"},paddingX:2,paddingY:4,mode:"bleed",tone:"primary",text:"Invite members",as:"a",loading:c,href:c?void 0:(u=e.id,"https://manage.sanity.io/projects/".concat(u,"/team/invite"))}),children:[c&&O.jsx(P.Box,{paddingY:5,paddingX:2,children:O.jsxs(P.Stack,{space:4,children:[O.jsx(P.Text,{align:"center",muted:!0,size:1,children:O.jsx(P.Spinner,{})}),O.jsx(P.Text,{align:"center",size:1,muted:!0,children:"Loading items..."})]})}),!c&&O.jsx(P.Stack,{space:3,padding:3,children:null==n?void 0:n.map((t=>{const n=e.members.find((e=>e.id===t.id)),r=(null==n?void 0:n.isRobot)?O.jsx(P.Text,{size:3,children:O.jsx(q.RobotIcon,{})}):O.jsx(Q,{tone:"transparent",children:(null==t?void 0:t.imageUrl)&&O.jsx("img",{src:t.imageUrl,alt:null==t?void 0:t.displayName})});return O.jsx(P.Box,{children:O.jsx(z.DefaultPreview,{title:t.displayName,subtitle:null==n?void 0:n.role,media:r})},t.id)}))})]});var u}const J=I.default(P.Box)(o||(o=k(["\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n\n &:before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 2.75em;\n height: 2.75em;\n border-radius: 50%;\n background: ",";\n opacity: 0.75;\n }\n"])),(e=>{let{theme:t}=e;return t.sanity.color.card.enabled.bg})),K=I.default(P.Flex)(s||(s=k(["\n &:hover {\n "," {\n &:before {\n opacity: 1;\n }\n }\n }\n"])),J),$=I.default(P.Card)(a||(a=k(["\n width: 100%;\n padding-bottom: calc(9 / 16 * 100%);\n position: relative;\n"]))),ee=I.default.img(l||(l=k(["\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n object-fit: cover;\n display: block;\n\n &:not([src]) {\n display: none;\n }\n"])));function te(e){const{title:t,posterURL:n,showPlayIcon:r,href:i,presenterName:o,presenterSubtitle:s}=e;return O.jsx(K,{flex:1,children:O.jsx(P.Card,{sizing:"border",flex:1,padding:2,radius:2,as:"a",href:i,target:"_blank",rel:"noopener noreferrer",style:{position:"relative"},children:O.jsxs(P.Flex,{direction:"column",style:{height:"100%"},children:[n&&O.jsxs($,{marginBottom:1,children:[O.jsx(ee,{src:n}),r&&O.jsx(J,{display:"flex",children:O.jsx(P.Text,{align:"center",children:O.jsx(q.PlayIcon,{})})})]}),O.jsxs(P.Flex,{direction:"column",justify:"space-between",paddingY:2,flex:1,children:[O.jsx(P.Heading,{as:"h3",size:1,children:t}),O.jsx(P.Box,{marginTop:4,children:O.jsxs(P.Stack,{space:2,flex:1,children:[O.jsx(P.Text,{size:1,children:o}),O.jsx(P.Text,{size:0,style:{opacity:.7},children:s})]})})]})]})})})}const ne={projectId:"3do82whm",dataset:"next"};function re(e){const{templateRepoId:t}=e,[n,r]=S.useState([]),{getFeed:i,urlBuilder:o}=function(){const e=Y();return S.useMemo((()=>({getFeed:t=>{const n=t?"/addons/dashboard?templateRepoId=".concat(t):"/addons/dashboard";return e.observable.request({uri:n,withCredentials:!1})},urlBuilder:R.default(ne)})),[e])}();S.useEffect((()=>{const e=i(t).subscribe((e=>{r(e.items)}));return()=>{e.unsubscribe()}}),[r,i,t]);return O.jsx(H,{header:"Learn about Sanity",children:O.jsx(P.Flex,{as:"ul",overflow:"auto",align:"stretch",paddingY:2,children:null==n?void 0:n.map(((e,t)=>{var r;if(!e.title||!e.guideOrTutorial&&!e.externalLink)return null;const i=e.presenter||(null==(r=e.guideOrTutorial)?void 0:r.presenter)||{},s=e.category,{guideOrTutorial:a={}}=e,l=(a.slug?(d=a.slug,"tutorial"===(c=a._type)?"https://www.sanity.io/docs/tutorials/".concat(d.current):"guide"===c&&"https://www.sanity.io/docs/guides/".concat(d.current)):e.externalLink)||e.externalLink;var d,c;return O.jsx(P.Flex,{as:"li",paddingRight:t<(null==n?void 0:n.length)-1?1:3,paddingLeft:0===t?3:0,align:"stretch",style:{minWidth:272,width:"30%"},children:O.jsx(te,{title:e.title,href:null!=l?l:"",presenterName:i.name,presenterSubtitle:s,showPlayIcon:e.hasVideo,posterURL:e.poster?o.image(e.poster).height(360).url():void 0})},e._id)}))})})}function ie(e){return O.jsx(P.Container,{width:4,padding:4,sizing:"border",style:{height:"100%",overflowY:"auto"},children:e.children})}const oe=function(){return C.css(d||(d=k(["\n @media (min-width: ","px) {\n ","\n }\n "])),(e=>{let{theme:t}=e;return t.sanity.media[0]}),C.css(...arguments))},se=function(){return C.css(c||(c=k(["\n @media (min-width: ","px) {\n ","\n }\n "])),(e=>{let{theme:t}=e;return t.sanity.media[2]}),C.css(...arguments))},ae=I.default(P.Grid)(u||(u=k(["\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n\n & > div {\n overflow: hidden;\n }\n\n & > div[data-width='medium'] {\n ","\n }\n\n & > div[data-width='large'] {\n ","\n\n ","\n }\n\n & > div[data-width='full'] {\n ","\n }\n\n & > div[data-height='medium'] {\n ","\n }\n\n & > div[data-height='large'] {\n ","\n\n ","\n }\n\n & > div[data-height='full'] {\n ","\n }\n"])),oe(h||(h=k(["\n grid-column: span 2;\n "]))),oe(p||(p=k(["\n grid-column: span 2;\n "]))),se(g||(g=k(["\n grid-column: span 3;\n "]))),oe(f||(f=k(["\n grid-column: 1 / -1;\n "]))),oe(x||(x=k(["\n grid-row: span 2;\n "]))),oe(m||(m=k(["\n grid-row: span 2;\n "]))),se(j||(j=k(["\n grid-row: span 3;\n "]))),se(b||(b=k(["\n grid-row: 1 / -1;\n "])))),le=[],de={};function ce(e){const{config:{layout:t=de,widgets:n=le}}=e;return O.jsxs(ae,{autoFlow:"row dense","data-width":t.width||"auto","data-height":t.height||"auto",gap:4,children:[n.length?null:O.jsx(P.Card,{padding:4,shadow:1,tone:"primary",children:O.jsx(P.Text,{align:"center",children:"Add some widgets to populate this space."})}),n.map(((e,t)=>"__experimental_group"===e.type?O.jsx(ce,{config:e},t):e.component?O.jsx(U,w({},e),t):O.jsxs(P.Box,{children:[e.name," is missing widget component"]},t)))]})}function ue(e){let{config:t}=e;return t?O.jsx(A.Provider,{value:t,children:O.jsx(ie,{children:O.jsx(ce,{config:t})})}):null}const he={stroke:"currentColor",strokeWidth:1.2},pe=()=>O.jsxs("svg",{"data-sanity-icon":!0,viewBox:"0 0 25 25",fill:"none",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid",width:"1em",height:"1em",children:[O.jsx("path",{d:"M19.5 19.5H5.5V5.5H19.5V19.5Z",style:he}),O.jsx("path",{d:"M5.5 12.5H19.5",style:he}),O.jsx("path",{d:"M14.5 19.5V12.5M10.5 12.5V5.5",style:he})]}),ge=z.definePlugin((function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};var t,n,r,i,o;const s={layout:null!=(t=e.defaultLayout)?t:{},widgets:null!=(n=e.widgets)?n:[]},a=null!=(r=e.title)?r:"Dashboard",l=null!=(i=e.name)?i:"dashboard",d=null!=(o=e.icon)?o:pe;return{name:"dashboard",tools:(e,t)=>[...e,{title:a,name:l,icon:d,component:()=>O.jsx(ue,{config:s})}]}}));exports.DashboardWidgetContainer=H,exports.dashboardTool=ge,exports.projectInfoWidget=function(e){var t;return{name:"project-info",component:G,layout:null!=(t=null==e?void 0:e.layout)?t:{width:"medium"}}},exports.projectUsersWidget=function(e){return{name:"project-info",component:Z,layout:null==e?void 0:e.layout}},exports.sanityTutorialsWidget=function(e){var t;return{name:"sanity-tutorials",component:re,layout:null!=(t=null==e?void 0:e.layout)?t:{width:"full"}}};
2
2
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/components/DashboardWidgetContainer.tsx","../src/versionedClient.ts","../src/containers/DashboardContext.tsx","../src/containers/WidgetContainer.tsx","../src/widgets/projectInfo/ProjectInfo.tsx","../src/widgets/projectUsers/ProjectUsers.tsx","../src/widgets/sanityTutorials/Tutorial.tsx","../src/widgets/sanityTutorials/dataAdapter.ts","../src/widgets/sanityTutorials/SanityTutorials.tsx","../src/components/DashboardLayout.tsx","../src/components/WidgetGroup.tsx","../src/containers/Dashboard.tsx","../src/plugin.tsx","../src/widgets/projectInfo/index.ts","../src/widgets/projectUsers/index.ts","../src/widgets/sanityTutorials/index.ts"],"sourcesContent":["import React, {forwardRef} from 'react'\nimport {Card, Box, Heading} from '@sanity/ui'\nimport styled from 'styled-components'\n\nconst Root = styled(Card)`\n display: flex;\n flex-direction: column;\n justify-content: stretch;\n height: 100%;\n box-sizing: border-box;\n position: relative;\n`\n\nconst Header = styled(Card)`\n position: sticky;\n top: 0;\n z-index: 2;\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n`\n\nconst Footer = styled(Card)`\n position: sticky;\n overflow: hidden;\n bottom: 0;\n z-index: 2;\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n margin-top: auto;\n`\n\nconst Content = styled(Box)`\n position: relative;\n z-index: 1;\n height: stretch;\n min-height: 21.5em;\n\n @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {\n overflow-y: auto;\n outline: none;\n }\n`\n\ninterface DashboardWidgetProps {\n header?: string\n children: React.ReactNode\n footer?: React.ReactNode\n}\n\nexport const DashboardWidgetContainer = forwardRef(function DashboardWidgetContainer(\n props: DashboardWidgetProps,\n ref: React.Ref<HTMLDivElement>\n) {\n const {header, children, footer} = props\n\n return (\n <Root radius={3} display=\"flex\" ref={ref}>\n {header && (\n <Header borderBottom paddingX={3} paddingY={4}>\n <Heading size={1} textOverflow=\"ellipsis\">\n {header}\n </Heading>\n </Header>\n )}\n {children && <Content>{children}</Content>}\n {footer && <Footer borderTop>{footer}</Footer>}\n </Root>\n )\n})\n","import {useClient} from 'sanity'\n\nexport function useVersionedClient() {\n return useClient({apiVersion: '1'})\n}\n","import {createContext, useContext} from 'react'\nimport {DashboardConfig} from '../types'\n\nexport const DashboardContext = createContext<DashboardConfig>({widgets: []})\n\nexport function useDashboardConfig(): DashboardConfig {\n return useContext(DashboardContext)\n}\n","import React, {createElement, useMemo} from 'react'\nimport {useDashboardConfig} from './DashboardContext'\nimport {Card} from '@sanity/ui'\nimport {DashboardWidget} from '../types'\n\nexport function WidgetContainer(props: DashboardWidget) {\n const config = useDashboardConfig()\n const layout = useMemo(\n () => ({\n ...(props.layout || {}),\n ...(config.layout || {}),\n }),\n [props.layout, config.layout]\n )\n\n return (\n <Card shadow={1} data-width={layout.width} data-height={layout.height}>\n {createElement(props.component, {})}\n </Card>\n )\n}\n","import React, {useEffect, useMemo, useState} from 'react'\nimport {Box, Card, Stack, Heading, Grid, Label, Text, Code, Button} from '@sanity/ui'\nimport {useVersionedClient} from '../../versionedClient'\nimport {Subscription} from 'rxjs'\nimport {WidgetContainer} from '../../containers/WidgetContainer'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\nimport {DashboardWidget} from '../../types'\n\nexport interface ProjectInfoProps {\n __experimental_before?: DashboardWidget[]\n data: ProjectData[]\n}\n\ninterface App {\n title: string\n rows?: App[]\n value?: string | {error: string}\n}\n\ninterface ProjectData {\n title: string\n category?: string\n}\n\nfunction isUrl(url?: string) {\n return url && /^https?:\\/\\//.test(`${url}`)\n}\n\nfunction getGraphQlUrl(projectId: string, dataset: string) {\n return `https://${projectId}.api.sanity.io/v1/graphql/${dataset}/default`\n}\n\nfunction getGroqUrl(projectId: string, dataset: string) {\n return `https://${projectId}.api.sanity.io/v1/groq/${dataset}`\n}\n\nfunction getManageUrl(projectId: string) {\n return `https://manage.sanity.io/projects/${projectId}`\n}\n\nconst NO_EXPERIMENTAL: DashboardWidget[] = []\nconst NO_DATA: ProjectData[] = []\n\nexport function ProjectInfo(props: ProjectInfoProps) {\n const {__experimental_before = NO_EXPERIMENTAL, data = NO_DATA} = props\n const [studioHost, setStudioHost] = useState<string | {error: string} | undefined>()\n const [graphqlApi, setGraphQlApi] = useState<string | {error: string} | undefined>()\n const versionedClient = useVersionedClient()\n const {projectId = 'unknown', dataset = 'unknown'} = versionedClient.config()\n\n useEffect(() => {\n const subscriptions: Subscription[] = []\n\n subscriptions.push(\n versionedClient.observable\n .request<{studioHost: string}>({uri: `/projects/${projectId}`})\n .subscribe({\n next: (result) => {\n const {studioHost: host} = result\n setStudioHost(host ? `https://${host}.sanity.studio` : undefined)\n },\n error: (error) => {\n console.error('Error while looking for studioHost', error)\n setStudioHost({\n error: 'Something went wrong while looking up studioHost. See console.',\n })\n },\n })\n )\n\n // ping assumed graphql endpoint\n subscriptions.push(\n versionedClient.observable\n .request({\n method: 'HEAD',\n uri: `/graphql/${dataset}/default`,\n })\n .subscribe({\n next: () => setGraphQlApi(getGraphQlUrl(projectId, dataset)),\n error: (error) => {\n if (error.statusCode === 404) {\n setGraphQlApi(undefined)\n } else {\n console.error('Error while looking for graphqlApi', error)\n setGraphQlApi({\n error: 'Something went wrong while looking up graphqlApi. See console.',\n })\n }\n },\n })\n )\n\n return () => {\n subscriptions.forEach((s) => s.unsubscribe())\n }\n }, [dataset, projectId, versionedClient, setGraphQlApi, setStudioHost])\n\n const assembleTableRows = useMemo(() => {\n let result: App[] = [\n {\n title: 'Sanity project',\n rows: [\n {title: 'Project ID', value: projectId},\n {title: 'Dataset', value: dataset},\n ],\n },\n ]\n\n // Handle any apps\n const apps: App[] = [\n studioHost ? {title: 'Studio', value: studioHost} : null,\n ...data.filter((item) => item.category === 'apps'),\n ].filter((a): a is App => !!a)\n if (apps.length > 0) {\n result = result.concat([{title: 'Apps', rows: apps}])\n }\n\n // Handle APIs\n result = result.concat(\n [\n {\n title: 'APIs',\n rows: [\n {title: 'GROQ', value: getGroqUrl(projectId, dataset)},\n {\n title: 'GraphQL',\n value: (typeof graphqlApi === 'object' ? 'Error' : graphqlApi) ?? 'Not deployed',\n },\n ],\n },\n ],\n data.filter((item) => item.category === 'apis')\n )\n\n // Handle whatever else there might be\n const otherStuff: Record<string, ProjectData[]> = {}\n data.forEach((item) => {\n if (item.category && item.category !== 'apps' && item.category !== 'apis') {\n if (!otherStuff[item.category]) {\n otherStuff[item.category] = []\n }\n otherStuff[item.category].push(item)\n }\n })\n Object.keys(otherStuff).forEach((category) => {\n result.push({title: category, rows: otherStuff[category]})\n })\n\n return result\n }, [graphqlApi, studioHost, projectId, dataset, data])\n\n return (\n <>\n {__experimental_before.map((widgetConfig, idx) => (\n <WidgetContainer key={idx} {...widgetConfig} />\n ))}\n <Box height=\"fill\" marginTop={__experimental_before?.length > 0 ? 4 : 0}>\n <DashboardWidgetContainer\n footer={\n <Button\n style={{width: '100%'}}\n paddingX={2}\n paddingY={4}\n mode=\"bleed\"\n tone=\"primary\"\n text=\"Manage project\"\n as=\"a\"\n href={getManageUrl(projectId)}\n />\n }\n >\n <Card\n paddingY={4}\n radius={2}\n role=\"table\"\n aria-label=\"Project info\"\n aria-describedby=\"project_info_table\"\n >\n <Stack space={4}>\n <Box paddingX={3} as=\"header\">\n <Heading size={1} as=\"h2\" id=\"project_info_table\">\n Project info\n </Heading>\n </Box>\n {assembleTableRows.map((item) => {\n if (!item || !item.rows) {\n return null\n }\n\n return (\n <Stack key={item.title} space={3}>\n <Card borderBottom padding={3}>\n <Label size={0} muted role=\"columnheader\">\n {item.title}\n </Label>\n </Card>\n <Stack space={4} paddingX={3} role=\"rowgroup\">\n {item.rows.map((row) => {\n return (\n <Grid key={row.title} columns={2} role=\"row\">\n <Text weight=\"medium\" role=\"rowheader\">\n {row.title}\n </Text>\n {typeof row.value === 'object' && (\n <Text size={1}>{row.value?.error}</Text>\n )}\n {typeof row.value === 'string' && (\n <>\n {isUrl(row.value) ? (\n <Text size={1} role=\"cell\" style={{wordBreak: 'break-word'}}>\n <a href={row.value}>{row.value}</a>\n </Text>\n ) : (\n <Code size={1} role=\"cell\" style={{wordBreak: 'break-word'}}>\n {row.value}\n </Code>\n )}\n </>\n )}\n </Grid>\n )\n })}\n </Stack>\n </Stack>\n )\n })}\n </Stack>\n </Card>\n </DashboardWidgetContainer>\n </Box>\n </>\n )\n}\n","import React, {useCallback, useEffect, useState} from 'react'\nimport {from} from 'rxjs'\nimport {map, switchMap} from 'rxjs/operators'\nimport {Stack, Spinner, Card, Box, Text, Button} from '@sanity/ui'\nimport {RobotIcon} from '@sanity/icons'\nimport styled from 'styled-components'\nimport {DefaultPreview, useUserStore} from 'sanity'\nimport {useVersionedClient} from '../../versionedClient'\nimport {User} from 'sanity'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\n\nconst AvatarWrapper = styled(Card)`\n box-sizing: border-box;\n border-radius: 50%;\n border-color: transparent;\n overflow: hidden;\n width: 100%;\n height: 100%;\n\n & > img {\n width: 100%;\n height: auto;\n }\n`\n\nfunction getInviteUrl(projectId: string) {\n return `https://manage.sanity.io/projects/${projectId}/team/invite`\n}\n\ninterface Member {\n id: string\n role: string\n isRobot: boolean\n}\n\ninterface Project {\n id: string\n members: Member[]\n}\n\nexport function ProjectUsers() {\n const [project, setProject] = useState<Project | undefined>()\n const [users, setUsers] = useState<User[] | undefined>()\n const [error, setError] = useState<Error | undefined>()\n\n const userStore = useUserStore()\n const versionedClient = useVersionedClient()\n\n const fetchData = useCallback(() => {\n const {projectId} = versionedClient.config()\n const subscription = versionedClient.observable\n .request<Project>({\n uri: `/projects/${projectId}`,\n })\n .pipe(\n switchMap((_project) =>\n from(userStore.getUsers(_project.members.map((mem) => mem.id))).pipe(\n map((_users) => ({project: _project, users: _users}))\n )\n )\n )\n .subscribe({\n next: ({users: _users, project: _project}) => {\n setProject(_project)\n setUsers(\n (Array.isArray(_users) ? _users : [_users]).sort((userA, userB) =>\n sortUsersByRobotStatus(userA, userB, _project)\n )\n )\n },\n error: (e: Error) => setError(e),\n })\n\n return () => subscription.unsubscribe()\n }, [userStore, versionedClient])\n\n useEffect(() => fetchData(), [fetchData])\n\n const handleRetryFetch = useCallback(() => fetchData(), [fetchData])\n\n const isLoading = !users || !project\n\n if (error) {\n return (\n <DashboardWidgetContainer header=\"Project users\">\n <Box padding={4}>\n <Text>\n Something went wrong while fetching data. You could{' '}\n <a onClick={handleRetryFetch} title=\"Retry users fetch\" style={{cursor: 'pointer'}}>\n retry\n </a>\n ..?\n </Text>\n </Box>\n </DashboardWidgetContainer>\n )\n }\n\n return (\n <DashboardWidgetContainer\n header=\"Project users\"\n footer={\n <Button\n style={{width: '100%'}}\n paddingX={2}\n paddingY={4}\n mode=\"bleed\"\n tone=\"primary\"\n text=\"Invite members\"\n as=\"a\"\n loading={isLoading}\n href={isLoading ? undefined : getInviteUrl(project.id)}\n />\n }\n >\n {isLoading && (\n <Box paddingY={5} paddingX={2}>\n <Stack space={4}>\n <Text align=\"center\" muted size={1}>\n <Spinner />\n </Text>\n <Text align=\"center\" size={1} muted>\n Loading items...\n </Text>\n </Stack>\n </Box>\n )}\n\n {!isLoading && (\n <Stack space={3} padding={3}>\n {users?.map((user) => {\n const membership = project.members.find((member) => member.id === user.id)\n const media = membership?.isRobot ? (\n <Text size={3}>\n <RobotIcon />\n </Text>\n ) : (\n <AvatarWrapper tone=\"transparent\">\n {user?.imageUrl && <img src={user.imageUrl} alt={user?.displayName} />}\n </AvatarWrapper>\n )\n return (\n <Box key={user.id}>\n <DefaultPreview\n title={user.displayName}\n subtitle={membership?.role}\n media={media}\n />\n </Box>\n )\n })}\n </Stack>\n )}\n </DashboardWidgetContainer>\n )\n}\n\nfunction sortUsersByRobotStatus(userA: User, userB: User, project: Project) {\n const {members} = project\n const membershipA = members.find((member) => member.id === userA?.id)\n const membershipB = members.find((member) => member.id === userB?.id)\n if (membershipA?.isRobot) {\n return 1\n }\n if (membershipB?.isRobot) {\n return -1\n }\n return 0\n}\n","import React from 'react'\nimport {Card, Box, Heading, Flex, Text, Stack} from '@sanity/ui'\nimport {PlayIcon} from '@sanity/icons'\nimport styled from 'styled-components'\n\nconst PlayIconBox = styled(Box)`\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n\n &:before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 2.75em;\n height: 2.75em;\n border-radius: 50%;\n background: ${({theme}) => theme.sanity.color.card.enabled.bg};\n opacity: 0.75;\n }\n`\n\nconst Root = styled(Flex)`\n &:hover {\n ${PlayIconBox} {\n &:before {\n opacity: 1;\n }\n }\n }\n`\n\nconst PosterCard = styled(Card)`\n width: 100%;\n padding-bottom: calc(9 / 16 * 100%);\n position: relative;\n`\n\nconst Poster = styled.img`\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n object-fit: cover;\n display: block;\n\n &:not([src]) {\n display: none;\n }\n`\n\nexport interface TutorialProps {\n title: string\n posterURL?: string\n href: string\n showPlayIcon?: boolean\n presenterName?: string\n presenterSubtitle?: string\n}\n\nexport function Tutorial(props: TutorialProps) {\n const {title, posterURL, showPlayIcon, href, presenterName, presenterSubtitle} = props\n\n return (\n <Root flex={1}>\n <Card\n sizing=\"border\"\n flex={1}\n padding={2}\n radius={2}\n as=\"a\"\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{position: 'relative'}}\n >\n <Flex direction=\"column\" style={{height: '100%'}}>\n {posterURL && (\n <PosterCard marginBottom={1}>\n <Poster src={posterURL} />\n {showPlayIcon && (\n <PlayIconBox display=\"flex\">\n <Text align=\"center\">\n <PlayIcon />\n </Text>\n </PlayIconBox>\n )}\n </PosterCard>\n )}\n <Flex direction=\"column\" justify=\"space-between\" paddingY={2} flex={1}>\n <Heading as=\"h3\" size={1}>\n {title}\n </Heading>\n <Box marginTop={4}>\n <Stack space={2} flex={1}>\n <Text size={1}>{presenterName}</Text>\n <Text size={0} style={{opacity: 0.7}}>\n {presenterSubtitle}\n </Text>\n </Stack>\n </Box>\n </Flex>\n </Flex>\n </Card>\n </Root>\n )\n}\n","import {useMemo} from 'react'\nimport {useVersionedClient} from '../../versionedClient'\nimport imageUrlBuilder from '@sanity/image-url'\n\nconst tutorialsProjectConfig = {\n projectId: '3do82whm',\n dataset: 'next',\n}\n\nexport interface Guide {\n _type?: string\n slug?: {current: string}\n presenter?: {\n name?: string\n }\n}\n\nexport interface FeedItem {\n _id: string\n title?: string\n poster?: string\n category?: string\n guideOrTutorial?: Guide\n externalLink?: string\n presenter?: {\n name?: string\n }\n hasVideo?: boolean\n}\n\nexport function useDataAdapter() {\n const versionedClient = useVersionedClient()\n return useMemo(\n () => ({\n getFeed: (templateRepoId: string) => {\n const uri = templateRepoId\n ? `/addons/dashboard?templateRepoId=${templateRepoId}`\n : '/addons/dashboard'\n return versionedClient.observable.request<{items: FeedItem[]}>({\n uri,\n withCredentials: false,\n })\n },\n urlBuilder: imageUrlBuilder(tutorialsProjectConfig),\n }),\n [versionedClient]\n )\n}\n","import React, {useEffect, useState} from 'react'\nimport {Flex} from '@sanity/ui'\nimport {Tutorial} from './Tutorial'\nimport {FeedItem, Guide, useDataAdapter} from './dataAdapter'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\n\nfunction createUrl(slug: {current: string}, type?: string) {\n if (type === 'tutorial') {\n return `https://www.sanity.io/docs/tutorials/${slug.current}`\n } else if (type === 'guide') {\n return `https://www.sanity.io/docs/guides/${slug.current}`\n }\n return false\n}\n\nexport interface SanityTutorialsProps {\n templateRepoId: string\n}\n\nexport function SanityTutorials(props: SanityTutorialsProps) {\n const {templateRepoId} = props\n const [feedItems, setFeedItems] = useState<FeedItem[]>([])\n\n const {getFeed, urlBuilder} = useDataAdapter()\n\n useEffect(() => {\n const subscription = getFeed(templateRepoId).subscribe((response) => {\n setFeedItems(response.items)\n })\n return () => {\n subscription.unsubscribe()\n }\n }, [setFeedItems, getFeed, templateRepoId])\n\n const title = 'Learn about Sanity'\n\n return (\n <DashboardWidgetContainer header={title}>\n <Flex as=\"ul\" overflow=\"auto\" align=\"stretch\" paddingY={2}>\n {feedItems?.map((feedItem, index) => {\n if (!feedItem.title || (!feedItem.guideOrTutorial && !feedItem.externalLink)) {\n return null\n }\n const presenter = feedItem.presenter || feedItem.guideOrTutorial?.presenter || {}\n const subtitle = feedItem.category\n const {guideOrTutorial = {} as Guide} = feedItem\n const href =\n (guideOrTutorial.slug\n ? createUrl(guideOrTutorial.slug, guideOrTutorial._type)\n : feedItem.externalLink) || feedItem.externalLink\n\n return (\n <Flex\n as=\"li\"\n key={feedItem._id}\n paddingRight={index < feedItems?.length - 1 ? 1 : 3}\n paddingLeft={index === 0 ? 3 : 0}\n align=\"stretch\"\n style={{minWidth: 272, width: '30%'}}\n >\n <Tutorial\n title={feedItem.title}\n href={href ?? ''}\n presenterName={presenter.name}\n presenterSubtitle={subtitle}\n showPlayIcon={feedItem.hasVideo}\n posterURL={\n feedItem.poster ? urlBuilder.image(feedItem.poster).height(360).url() : undefined\n }\n />\n </Flex>\n )\n })}\n </Flex>\n </DashboardWidgetContainer>\n )\n}\n","import React, {PropsWithChildren} from 'react'\nimport {Container} from '@sanity/ui'\n\nexport function DashboardLayout(props: PropsWithChildren<{}>) {\n return (\n <Container width={4} padding={4} sizing=\"border\" style={{minHeight: '100%'}}>\n {props.children}\n </Container>\n )\n}\n","import React from 'react'\nimport styled, {css} from 'styled-components'\nimport {Box, Card, Grid, Text} from '@sanity/ui'\nimport {WidgetContainer} from '../containers/WidgetContainer'\nimport {DashboardConfig, LayoutConfig, DashboardWidget} from '../types'\n\nconst media = {\n small: (...args: Parameters<typeof css>) =>\n css`\n @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {\n ${css(...args)}\n }\n `,\n medium: (...args: Parameters<typeof css>) =>\n css`\n @media (min-width: ${({theme}) => theme.sanity.media[2]}px) {\n ${css(...args)}\n }\n `,\n}\n\nconst Root = styled(Grid)`\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n\n & > div {\n overflow: hidden;\n }\n\n & > div[data-width='medium'] {\n ${media.small`\n grid-column: span 2;\n `}\n }\n\n & > div[data-width='large'] {\n ${media.small`\n grid-column: span 2;\n `}\n\n ${media.medium`\n grid-column: span 3;\n `}\n }\n\n & > div[data-width='full'] {\n ${media.small`\n grid-column: 1 / -1;\n `}\n }\n\n & > div[data-height='medium'] {\n ${media.small`\n grid-row: span 2;\n `}\n }\n\n & > div[data-height='large'] {\n ${media.small`\n grid-row: span 2;\n `}\n\n ${media.medium`\n grid-row: span 3;\n `}\n }\n\n & > div[data-height='full'] {\n ${media.medium`\n grid-row: 1 / -1;\n `}\n }\n`\n\nexport interface WidgetGroupProps {\n config: Partial<DashboardConfig>\n}\n\nconst NO_WIDGETS: DashboardWidget[] = []\nconst NO_LAYOUT: LayoutConfig = {}\n\nexport function WidgetGroup(props: WidgetGroupProps) {\n const {\n config: {layout = NO_LAYOUT, widgets = NO_WIDGETS},\n } = props\n return (\n <Root\n autoFlow=\"row dense\"\n data-width={layout.width || 'auto'}\n data-height={layout.height || 'auto'}\n gap={4}\n >\n {widgets.length ? null : (\n <Card padding={4} shadow={1} tone=\"primary\">\n <Text align=\"center\">Add some widgets to populate this space.</Text>\n </Card>\n )}\n {widgets.map((widgetConfig, index) => {\n if (widgetConfig.type === '__experimental_group') {\n return <WidgetGroup key={index} config={widgetConfig} />\n }\n if (widgetConfig.component) {\n return <WidgetContainer key={index} {...widgetConfig} />\n }\n return <Box key={index}>{widgetConfig.name} is missing widget component</Box>\n })}\n </Root>\n )\n}\n","import React from 'react'\nimport {DashboardLayout} from '../components/DashboardLayout'\nimport {WidgetGroup} from '../components/WidgetGroup'\nimport {DashboardContext} from './DashboardContext'\nimport {DashboardConfig} from '../types'\n\nexport function Dashboard({config}: {config: DashboardConfig}) {\n if (!config) {\n return null\n }\n\n return (\n <DashboardContext.Provider value={config}>\n <DashboardLayout>\n <WidgetGroup config={config} />\n </DashboardLayout>\n </DashboardContext.Provider>\n )\n}\n","import React, {CSSProperties} from 'react'\nimport {Dashboard} from './containers/Dashboard'\nimport {definePlugin} from 'sanity'\nimport {DashboardConfig, DashboardWidget, LayoutConfig} from './types'\n\nconst strokeStyle: CSSProperties = {\n stroke: 'currentColor',\n strokeWidth: 1.2,\n}\n\nconst DashboardIcon = () => (\n <svg\n data-sanity-icon\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n preserveAspectRatio=\"xMidYMid\"\n width=\"1em\"\n height=\"1em\"\n >\n <path d=\"M19.5 19.5H5.5V5.5H19.5V19.5Z\" style={strokeStyle} />\n <path d=\"M5.5 12.5H19.5\" style={strokeStyle} />\n <path d=\"M14.5 19.5V12.5M10.5 12.5V5.5\" style={strokeStyle} />\n </svg>\n)\n\nexport interface DashboardPluginConfig {\n widgets?: DashboardWidget[]\n\n /**\n * Will be used for widgets that do not define a layout directly.\n */\n defaultLayout?: LayoutConfig\n}\n\nexport const dashboardTool = definePlugin<DashboardPluginConfig>((config = {}) => {\n const pluginConfig: DashboardConfig = {\n layout: config.defaultLayout ?? {},\n widgets: config.widgets ?? [],\n }\n\n return {\n name: 'dashboard',\n tools: (prev, context) => {\n return [\n ...prev,\n {\n title: 'Dashboard',\n name: 'dashboard',\n icon: DashboardIcon,\n component: () => <Dashboard config={pluginConfig} />,\n },\n ]\n },\n }\n})\n","import {ProjectInfo} from './ProjectInfo'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function projectInfoWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'project-info',\n component: ProjectInfo,\n layout: config?.layout ?? {width: 'medium'},\n }\n}\n","import {ProjectUsers} from './ProjectUsers'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function projectUsersWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'project-info',\n component: ProjectUsers,\n layout: config?.layout,\n }\n}\n","import {SanityTutorials} from './SanityTutorials'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function sanityTutorialsWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'sanity-tutorials',\n component: SanityTutorials,\n layout: config?.layout ?? {width: 'full'},\n }\n}\n"],"names":["Root","styled","Card","_templateObject","_taggedTemplateLiteral","Header","_templateObject2","Footer","_templateObject3","Content","Box","_templateObject4","_ref","theme","sanity","media","DashboardWidgetContainer","forwardRef","props","ref","header","children","footer","jsxs","radius","display","jsx","borderBottom","paddingX","paddingY","Heading","size","textOverflow","borderTop","useVersionedClient","useClient","apiVersion","DashboardContext","createContext","widgets","WidgetContainer","config","useContext","layout","useMemo","shadow","width","height","createElement","component","getGroqUrl","projectId","dataset","getManageUrl","concat","NO_EXPERIMENTAL","NO_DATA","ProjectInfo","__experimental_before","data","studioHost","setStudioHost","useState","graphqlApi","setGraphQlApi","versionedClient","useEffect","subscriptions","push","observable","request","uri","subscribe","next","result","host","error","console","method","getGraphQlUrl","statusCode","forEach","s","unsubscribe","assembleTableRows","_a","title","rows","value","apps","filter","item","category","a","length","otherStuff","Object","keys","Fragment","map","widgetConfig","idx","_objectSpread","marginTop","Button","style","mode","tone","text","as","href","role","Stack","space","id","padding","Label","muted","row","url","Grid","columns","Text","weight","test","wordBreak","Code","AvatarWrapper","_templateObject5","ProjectUsers","project","setProject","users","setUsers","setError","userStore","useUserStore","fetchData","useCallback","subscription","pipe","switchMap","_project","from","getUsers","members","mem","_users","_ref2","Array","isArray","sort","userA","userB","membershipA","find","member","membershipB","isRobot","sortUsersByRobotStatus","e","handleRetryFetch","isLoading","onClick","cursor","loading","align","Spinner","user","membership","RobotIcon","imageUrl","src","alt","displayName","DefaultPreview","subtitle","PlayIconBox","_templateObject6","_ref3","color","card","enabled","bg","Flex","_templateObject7","PosterCard","_templateObject8","Poster","img","_templateObject9","Tutorial","posterURL","showPlayIcon","presenterName","presenterSubtitle","flex","sizing","target","rel","position","direction","marginBottom","PlayIcon","justify","opacity","tutorialsProjectConfig","SanityTutorials","templateRepoId","feedItems","setFeedItems","getFeed","urlBuilder","withCredentials","imageUrlBuilder","useDataAdapter","response","items","overflow","feedItem","index","guideOrTutorial","externalLink","presenter","slug","type","_type","current","paddingRight","paddingLeft","minWidth","name","hasVideo","poster","image","_id","DashboardLayout","Container","minHeight","css","_templateObject10","_ref4","_templateObject11","_ref5","_templateObject12","_templateObject15","_templateObject18","_templateObject20","NO_WIDGETS","NO_LAYOUT","WidgetGroup","autoFlow","gap","Dashboard","_ref6","Provider","strokeStyle","stroke","strokeWidth","DashboardIcon","viewBox","fill","xmlns","preserveAspectRatio","d","dashboardTool","definePlugin","arguments","undefined","_b","pluginConfig","defaultLayout","tools","prev","context","icon"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/components/DashboardWidgetContainer.tsx","../src/versionedClient.ts","../src/containers/DashboardContext.tsx","../src/containers/WidgetContainer.tsx","../src/widgets/projectInfo/ProjectInfo.tsx","../src/widgets/projectUsers/ProjectUsers.tsx","../src/widgets/sanityTutorials/Tutorial.tsx","../src/widgets/sanityTutorials/dataAdapter.ts","../src/widgets/sanityTutorials/SanityTutorials.tsx","../src/components/DashboardLayout.tsx","../src/components/WidgetGroup.tsx","../src/containers/Dashboard.tsx","../src/plugin.tsx","../src/widgets/projectInfo/index.ts","../src/widgets/projectUsers/index.ts","../src/widgets/sanityTutorials/index.ts"],"sourcesContent":["import React, {forwardRef} from 'react'\nimport {Card, Box, Heading} from '@sanity/ui'\nimport styled from 'styled-components'\n\nconst Root = styled(Card)`\n display: flex;\n flex-direction: column;\n justify-content: stretch;\n height: 100%;\n box-sizing: border-box;\n position: relative;\n`\n\nconst Header = styled(Card)`\n position: sticky;\n top: 0;\n z-index: 2;\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n`\n\nconst Footer = styled(Card)`\n position: sticky;\n overflow: hidden;\n bottom: 0;\n z-index: 2;\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n margin-top: auto;\n`\n\nconst Content = styled(Box)`\n position: relative;\n z-index: 1;\n height: stretch;\n min-height: 21.5em;\n\n @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {\n overflow-y: auto;\n outline: none;\n }\n`\n\ninterface DashboardWidgetProps {\n header?: string\n children: React.ReactNode\n footer?: React.ReactNode\n}\n\nexport const DashboardWidgetContainer = forwardRef(function DashboardWidgetContainer(\n props: DashboardWidgetProps,\n ref: React.Ref<HTMLDivElement>\n) {\n const {header, children, footer} = props\n\n return (\n <Root radius={3} display=\"flex\" ref={ref}>\n {header && (\n <Header borderBottom paddingX={3} paddingY={4}>\n <Heading size={1} textOverflow=\"ellipsis\">\n {header}\n </Heading>\n </Header>\n )}\n {children && <Content>{children}</Content>}\n {footer && <Footer borderTop>{footer}</Footer>}\n </Root>\n )\n})\n","import {useClient} from 'sanity'\n\nexport function useVersionedClient() {\n return useClient({apiVersion: '1'})\n}\n","import {createContext, useContext} from 'react'\nimport {DashboardConfig} from '../types'\n\nexport const DashboardContext = createContext<DashboardConfig>({widgets: []})\n\nexport function useDashboardConfig(): DashboardConfig {\n return useContext(DashboardContext)\n}\n","import React, {createElement, useMemo} from 'react'\nimport {useDashboardConfig} from './DashboardContext'\nimport {Card} from '@sanity/ui'\nimport {DashboardWidget} from '../types'\n\nexport function WidgetContainer(props: DashboardWidget) {\n const config = useDashboardConfig()\n const layout = useMemo(\n () => ({\n ...(props.layout || {}),\n ...(config.layout || {}),\n }),\n [props.layout, config.layout]\n )\n\n return (\n <Card shadow={1} data-width={layout.width} data-height={layout.height}>\n {createElement(props.component, {})}\n </Card>\n )\n}\n","import React, {useEffect, useMemo, useState} from 'react'\nimport {Box, Card, Stack, Heading, Grid, Label, Text, Code, Button} from '@sanity/ui'\nimport {useVersionedClient} from '../../versionedClient'\nimport {Subscription} from 'rxjs'\nimport {WidgetContainer} from '../../containers/WidgetContainer'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\nimport {DashboardWidget} from '../../types'\n\nexport interface ProjectInfoProps {\n __experimental_before?: DashboardWidget[]\n data: ProjectData[]\n}\n\ninterface App {\n title: string\n rows?: App[]\n value?: string | {error: string}\n}\n\ninterface ProjectData {\n title: string\n category?: string\n}\n\nfunction isUrl(url?: string) {\n return url && /^https?:\\/\\//.test(`${url}`)\n}\n\nfunction getGraphQlUrl(projectId: string, dataset: string) {\n return `https://${projectId}.api.sanity.io/v1/graphql/${dataset}/default`\n}\n\nfunction getGroqUrl(projectId: string, dataset: string) {\n return `https://${projectId}.api.sanity.io/v1/groq/${dataset}`\n}\n\nfunction getManageUrl(projectId: string) {\n return `https://manage.sanity.io/projects/${projectId}`\n}\n\nconst NO_EXPERIMENTAL: DashboardWidget[] = []\nconst NO_DATA: ProjectData[] = []\n\nexport function ProjectInfo(props: ProjectInfoProps) {\n const {__experimental_before = NO_EXPERIMENTAL, data = NO_DATA} = props\n const [studioHost, setStudioHost] = useState<string | {error: string} | undefined>()\n const [graphqlApi, setGraphQlApi] = useState<string | {error: string} | undefined>()\n const versionedClient = useVersionedClient()\n const {projectId = 'unknown', dataset = 'unknown'} = versionedClient.config()\n\n useEffect(() => {\n const subscriptions: Subscription[] = []\n\n subscriptions.push(\n versionedClient.observable\n .request<{studioHost: string}>({uri: `/projects/${projectId}`})\n .subscribe({\n next: (result) => {\n const {studioHost: host} = result\n setStudioHost(host ? `https://${host}.sanity.studio` : undefined)\n },\n error: (error) => {\n console.error('Error while looking for studioHost', error)\n setStudioHost({\n error: 'Something went wrong while looking up studioHost. See console.',\n })\n },\n })\n )\n\n // ping assumed graphql endpoint\n subscriptions.push(\n versionedClient.observable\n .request({\n method: 'HEAD',\n uri: `/graphql/${dataset}/default`,\n })\n .subscribe({\n next: () => setGraphQlApi(getGraphQlUrl(projectId, dataset)),\n error: (error) => {\n if (error.statusCode === 404) {\n setGraphQlApi(undefined)\n } else {\n console.error('Error while looking for graphqlApi', error)\n setGraphQlApi({\n error: 'Something went wrong while looking up graphqlApi. See console.',\n })\n }\n },\n })\n )\n\n return () => {\n subscriptions.forEach((s) => s.unsubscribe())\n }\n }, [dataset, projectId, versionedClient, setGraphQlApi, setStudioHost])\n\n const assembleTableRows = useMemo(() => {\n let result: App[] = [\n {\n title: 'Sanity project',\n rows: [\n {title: 'Project ID', value: projectId},\n {title: 'Dataset', value: dataset},\n ],\n },\n ]\n\n // Handle any apps\n const apps: App[] = [\n studioHost ? {title: 'Studio', value: studioHost} : null,\n ...data.filter((item) => item.category === 'apps'),\n ].filter((a): a is App => !!a)\n if (apps.length > 0) {\n result = result.concat([{title: 'Apps', rows: apps}])\n }\n\n // Handle APIs\n result = result.concat(\n [\n {\n title: 'APIs',\n rows: [\n {title: 'GROQ', value: getGroqUrl(projectId, dataset)},\n {\n title: 'GraphQL',\n value: (typeof graphqlApi === 'object' ? 'Error' : graphqlApi) ?? 'Not deployed',\n },\n ],\n },\n ],\n data.filter((item) => item.category === 'apis')\n )\n\n // Handle whatever else there might be\n const otherStuff: Record<string, ProjectData[]> = {}\n data.forEach((item) => {\n if (item.category && item.category !== 'apps' && item.category !== 'apis') {\n if (!otherStuff[item.category]) {\n otherStuff[item.category] = []\n }\n otherStuff[item.category].push(item)\n }\n })\n Object.keys(otherStuff).forEach((category) => {\n result.push({title: category, rows: otherStuff[category]})\n })\n\n return result\n }, [graphqlApi, studioHost, projectId, dataset, data])\n\n return (\n <>\n {__experimental_before.map((widgetConfig, idx) => (\n <WidgetContainer key={idx} {...widgetConfig} />\n ))}\n <Box height=\"fill\" marginTop={__experimental_before?.length > 0 ? 4 : 0}>\n <DashboardWidgetContainer\n footer={\n <Button\n style={{width: '100%'}}\n paddingX={2}\n paddingY={4}\n mode=\"bleed\"\n tone=\"primary\"\n text=\"Manage project\"\n as=\"a\"\n href={getManageUrl(projectId)}\n />\n }\n >\n <Card\n paddingY={4}\n radius={2}\n role=\"table\"\n aria-label=\"Project info\"\n aria-describedby=\"project_info_table\"\n >\n <Stack space={4}>\n <Box paddingX={3} as=\"header\">\n <Heading size={1} as=\"h2\" id=\"project_info_table\">\n Project info\n </Heading>\n </Box>\n {assembleTableRows.map((item) => {\n if (!item || !item.rows) {\n return null\n }\n\n return (\n <Stack key={item.title} space={3}>\n <Card borderBottom padding={3}>\n <Label size={0} muted role=\"columnheader\">\n {item.title}\n </Label>\n </Card>\n <Stack space={4} paddingX={3} role=\"rowgroup\">\n {item.rows.map((row) => {\n return (\n <Grid key={row.title} columns={2} role=\"row\">\n <Text weight=\"medium\" role=\"rowheader\">\n {row.title}\n </Text>\n {typeof row.value === 'object' && (\n <Text size={1}>{row.value?.error}</Text>\n )}\n {typeof row.value === 'string' && (\n <>\n {isUrl(row.value) ? (\n <Text size={1} role=\"cell\" style={{wordBreak: 'break-word'}}>\n <a href={row.value}>{row.value}</a>\n </Text>\n ) : (\n <Code size={1} role=\"cell\" style={{wordBreak: 'break-word'}}>\n {row.value}\n </Code>\n )}\n </>\n )}\n </Grid>\n )\n })}\n </Stack>\n </Stack>\n )\n })}\n </Stack>\n </Card>\n </DashboardWidgetContainer>\n </Box>\n </>\n )\n}\n","import React, {useCallback, useEffect, useState} from 'react'\nimport {from} from 'rxjs'\nimport {map, switchMap} from 'rxjs/operators'\nimport {Stack, Spinner, Card, Box, Text, Button} from '@sanity/ui'\nimport {RobotIcon} from '@sanity/icons'\nimport styled from 'styled-components'\nimport {DefaultPreview, useUserStore} from 'sanity'\nimport {useVersionedClient} from '../../versionedClient'\nimport {User} from 'sanity'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\n\nconst AvatarWrapper = styled(Card)`\n box-sizing: border-box;\n border-radius: 50%;\n border-color: transparent;\n overflow: hidden;\n width: 100%;\n height: 100%;\n\n & > img {\n width: 100%;\n height: auto;\n }\n`\n\nfunction getInviteUrl(projectId: string) {\n return `https://manage.sanity.io/projects/${projectId}/team/invite`\n}\n\ninterface Member {\n id: string\n role: string\n isRobot: boolean\n}\n\ninterface Project {\n id: string\n members: Member[]\n}\n\nexport function ProjectUsers() {\n const [project, setProject] = useState<Project | undefined>()\n const [users, setUsers] = useState<User[] | undefined>()\n const [error, setError] = useState<Error | undefined>()\n\n const userStore = useUserStore()\n const versionedClient = useVersionedClient()\n\n const fetchData = useCallback(() => {\n const {projectId} = versionedClient.config()\n const subscription = versionedClient.observable\n .request<Project>({\n uri: `/projects/${projectId}`,\n })\n .pipe(\n switchMap((_project) =>\n from(userStore.getUsers(_project.members.map((mem) => mem.id))).pipe(\n map((_users) => ({project: _project, users: _users}))\n )\n )\n )\n .subscribe({\n next: ({users: _users, project: _project}) => {\n setProject(_project)\n setUsers(\n (Array.isArray(_users) ? _users : [_users]).sort((userA, userB) =>\n sortUsersByRobotStatus(userA, userB, _project)\n )\n )\n },\n error: (e: Error) => setError(e),\n })\n\n return () => subscription.unsubscribe()\n }, [userStore, versionedClient])\n\n useEffect(() => fetchData(), [fetchData])\n\n const handleRetryFetch = useCallback(() => fetchData(), [fetchData])\n\n const isLoading = !users || !project\n\n if (error) {\n return (\n <DashboardWidgetContainer header=\"Project users\">\n <Box padding={4}>\n <Text>\n Something went wrong while fetching data. You could{' '}\n <a onClick={handleRetryFetch} title=\"Retry users fetch\" style={{cursor: 'pointer'}}>\n retry\n </a>\n ..?\n </Text>\n </Box>\n </DashboardWidgetContainer>\n )\n }\n\n return (\n <DashboardWidgetContainer\n header=\"Project users\"\n footer={\n <Button\n style={{width: '100%'}}\n paddingX={2}\n paddingY={4}\n mode=\"bleed\"\n tone=\"primary\"\n text=\"Invite members\"\n as=\"a\"\n loading={isLoading}\n href={isLoading ? undefined : getInviteUrl(project.id)}\n />\n }\n >\n {isLoading && (\n <Box paddingY={5} paddingX={2}>\n <Stack space={4}>\n <Text align=\"center\" muted size={1}>\n <Spinner />\n </Text>\n <Text align=\"center\" size={1} muted>\n Loading items...\n </Text>\n </Stack>\n </Box>\n )}\n\n {!isLoading && (\n <Stack space={3} padding={3}>\n {users?.map((user) => {\n const membership = project.members.find((member) => member.id === user.id)\n const media = membership?.isRobot ? (\n <Text size={3}>\n <RobotIcon />\n </Text>\n ) : (\n <AvatarWrapper tone=\"transparent\">\n {user?.imageUrl && <img src={user.imageUrl} alt={user?.displayName} />}\n </AvatarWrapper>\n )\n return (\n <Box key={user.id}>\n <DefaultPreview\n title={user.displayName}\n subtitle={membership?.role}\n media={media}\n />\n </Box>\n )\n })}\n </Stack>\n )}\n </DashboardWidgetContainer>\n )\n}\n\nfunction sortUsersByRobotStatus(userA: User, userB: User, project: Project) {\n const {members} = project\n const membershipA = members.find((member) => member.id === userA?.id)\n const membershipB = members.find((member) => member.id === userB?.id)\n if (membershipA?.isRobot) {\n return 1\n }\n if (membershipB?.isRobot) {\n return -1\n }\n return 0\n}\n","import React from 'react'\nimport {Card, Box, Heading, Flex, Text, Stack} from '@sanity/ui'\nimport {PlayIcon} from '@sanity/icons'\nimport styled from 'styled-components'\n\nconst PlayIconBox = styled(Box)`\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n\n &:before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 2.75em;\n height: 2.75em;\n border-radius: 50%;\n background: ${({theme}) => theme.sanity.color.card.enabled.bg};\n opacity: 0.75;\n }\n`\n\nconst Root = styled(Flex)`\n &:hover {\n ${PlayIconBox} {\n &:before {\n opacity: 1;\n }\n }\n }\n`\n\nconst PosterCard = styled(Card)`\n width: 100%;\n padding-bottom: calc(9 / 16 * 100%);\n position: relative;\n`\n\nconst Poster = styled.img`\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n object-fit: cover;\n display: block;\n\n &:not([src]) {\n display: none;\n }\n`\n\nexport interface TutorialProps {\n title: string\n posterURL?: string\n href: string\n showPlayIcon?: boolean\n presenterName?: string\n presenterSubtitle?: string\n}\n\nexport function Tutorial(props: TutorialProps) {\n const {title, posterURL, showPlayIcon, href, presenterName, presenterSubtitle} = props\n\n return (\n <Root flex={1}>\n <Card\n sizing=\"border\"\n flex={1}\n padding={2}\n radius={2}\n as=\"a\"\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{position: 'relative'}}\n >\n <Flex direction=\"column\" style={{height: '100%'}}>\n {posterURL && (\n <PosterCard marginBottom={1}>\n <Poster src={posterURL} />\n {showPlayIcon && (\n <PlayIconBox display=\"flex\">\n <Text align=\"center\">\n <PlayIcon />\n </Text>\n </PlayIconBox>\n )}\n </PosterCard>\n )}\n <Flex direction=\"column\" justify=\"space-between\" paddingY={2} flex={1}>\n <Heading as=\"h3\" size={1}>\n {title}\n </Heading>\n <Box marginTop={4}>\n <Stack space={2} flex={1}>\n <Text size={1}>{presenterName}</Text>\n <Text size={0} style={{opacity: 0.7}}>\n {presenterSubtitle}\n </Text>\n </Stack>\n </Box>\n </Flex>\n </Flex>\n </Card>\n </Root>\n )\n}\n","import {useMemo} from 'react'\nimport {useVersionedClient} from '../../versionedClient'\nimport imageUrlBuilder from '@sanity/image-url'\n\nconst tutorialsProjectConfig = {\n projectId: '3do82whm',\n dataset: 'next',\n}\n\nexport interface Guide {\n _type?: string\n slug?: {current: string}\n presenter?: {\n name?: string\n }\n}\n\nexport interface FeedItem {\n _id: string\n title?: string\n poster?: string\n category?: string\n guideOrTutorial?: Guide\n externalLink?: string\n presenter?: {\n name?: string\n }\n hasVideo?: boolean\n}\n\nexport function useDataAdapter() {\n const versionedClient = useVersionedClient()\n return useMemo(\n () => ({\n getFeed: (templateRepoId: string) => {\n const uri = templateRepoId\n ? `/addons/dashboard?templateRepoId=${templateRepoId}`\n : '/addons/dashboard'\n return versionedClient.observable.request<{items: FeedItem[]}>({\n uri,\n withCredentials: false,\n })\n },\n urlBuilder: imageUrlBuilder(tutorialsProjectConfig),\n }),\n [versionedClient]\n )\n}\n","import React, {useEffect, useState} from 'react'\nimport {Flex} from '@sanity/ui'\nimport {Tutorial} from './Tutorial'\nimport {FeedItem, Guide, useDataAdapter} from './dataAdapter'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\n\nfunction createUrl(slug: {current: string}, type?: string) {\n if (type === 'tutorial') {\n return `https://www.sanity.io/docs/tutorials/${slug.current}`\n } else if (type === 'guide') {\n return `https://www.sanity.io/docs/guides/${slug.current}`\n }\n return false\n}\n\nexport interface SanityTutorialsProps {\n templateRepoId: string\n}\n\nexport function SanityTutorials(props: SanityTutorialsProps) {\n const {templateRepoId} = props\n const [feedItems, setFeedItems] = useState<FeedItem[]>([])\n\n const {getFeed, urlBuilder} = useDataAdapter()\n\n useEffect(() => {\n const subscription = getFeed(templateRepoId).subscribe((response) => {\n setFeedItems(response.items)\n })\n return () => {\n subscription.unsubscribe()\n }\n }, [setFeedItems, getFeed, templateRepoId])\n\n const title = 'Learn about Sanity'\n\n return (\n <DashboardWidgetContainer header={title}>\n <Flex as=\"ul\" overflow=\"auto\" align=\"stretch\" paddingY={2}>\n {feedItems?.map((feedItem, index) => {\n if (!feedItem.title || (!feedItem.guideOrTutorial && !feedItem.externalLink)) {\n return null\n }\n const presenter = feedItem.presenter || feedItem.guideOrTutorial?.presenter || {}\n const subtitle = feedItem.category\n const {guideOrTutorial = {} as Guide} = feedItem\n const href =\n (guideOrTutorial.slug\n ? createUrl(guideOrTutorial.slug, guideOrTutorial._type)\n : feedItem.externalLink) || feedItem.externalLink\n\n return (\n <Flex\n as=\"li\"\n key={feedItem._id}\n paddingRight={index < feedItems?.length - 1 ? 1 : 3}\n paddingLeft={index === 0 ? 3 : 0}\n align=\"stretch\"\n style={{minWidth: 272, width: '30%'}}\n >\n <Tutorial\n title={feedItem.title}\n href={href ?? ''}\n presenterName={presenter.name}\n presenterSubtitle={subtitle}\n showPlayIcon={feedItem.hasVideo}\n posterURL={\n feedItem.poster ? urlBuilder.image(feedItem.poster).height(360).url() : undefined\n }\n />\n </Flex>\n )\n })}\n </Flex>\n </DashboardWidgetContainer>\n )\n}\n","import React, {PropsWithChildren} from 'react'\nimport {Container} from '@sanity/ui'\n\nexport function DashboardLayout(props: PropsWithChildren<{}>) {\n return (\n <Container width={4} padding={4} sizing=\"border\" style={{height: '100%', overflowY: 'auto'}}>\n {props.children}\n </Container>\n )\n}\n","import React from 'react'\nimport styled, {css} from 'styled-components'\nimport {Box, Card, Grid, Text} from '@sanity/ui'\nimport {WidgetContainer} from '../containers/WidgetContainer'\nimport {DashboardConfig, LayoutConfig, DashboardWidget} from '../types'\n\nconst media = {\n small: (...args: Parameters<typeof css>) =>\n css`\n @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {\n ${css(...args)}\n }\n `,\n medium: (...args: Parameters<typeof css>) =>\n css`\n @media (min-width: ${({theme}) => theme.sanity.media[2]}px) {\n ${css(...args)}\n }\n `,\n}\n\nconst Root = styled(Grid)`\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n\n & > div {\n overflow: hidden;\n }\n\n & > div[data-width='medium'] {\n ${media.small`\n grid-column: span 2;\n `}\n }\n\n & > div[data-width='large'] {\n ${media.small`\n grid-column: span 2;\n `}\n\n ${media.medium`\n grid-column: span 3;\n `}\n }\n\n & > div[data-width='full'] {\n ${media.small`\n grid-column: 1 / -1;\n `}\n }\n\n & > div[data-height='medium'] {\n ${media.small`\n grid-row: span 2;\n `}\n }\n\n & > div[data-height='large'] {\n ${media.small`\n grid-row: span 2;\n `}\n\n ${media.medium`\n grid-row: span 3;\n `}\n }\n\n & > div[data-height='full'] {\n ${media.medium`\n grid-row: 1 / -1;\n `}\n }\n`\n\nexport interface WidgetGroupProps {\n config: Partial<DashboardConfig>\n}\n\nconst NO_WIDGETS: DashboardWidget[] = []\nconst NO_LAYOUT: LayoutConfig = {}\n\nexport function WidgetGroup(props: WidgetGroupProps) {\n const {\n config: {layout = NO_LAYOUT, widgets = NO_WIDGETS},\n } = props\n return (\n <Root\n autoFlow=\"row dense\"\n data-width={layout.width || 'auto'}\n data-height={layout.height || 'auto'}\n gap={4}\n >\n {widgets.length ? null : (\n <Card padding={4} shadow={1} tone=\"primary\">\n <Text align=\"center\">Add some widgets to populate this space.</Text>\n </Card>\n )}\n {widgets.map((widgetConfig, index) => {\n if (widgetConfig.type === '__experimental_group') {\n return <WidgetGroup key={index} config={widgetConfig} />\n }\n if (widgetConfig.component) {\n return <WidgetContainer key={index} {...widgetConfig} />\n }\n return <Box key={index}>{widgetConfig.name} is missing widget component</Box>\n })}\n </Root>\n )\n}\n","import React from 'react'\nimport {DashboardLayout} from '../components/DashboardLayout'\nimport {WidgetGroup} from '../components/WidgetGroup'\nimport {DashboardContext} from './DashboardContext'\nimport {DashboardConfig} from '../types'\n\nexport function Dashboard({config}: {config: DashboardConfig}) {\n if (!config) {\n return null\n }\n\n return (\n <DashboardContext.Provider value={config}>\n <DashboardLayout>\n <WidgetGroup config={config} />\n </DashboardLayout>\n </DashboardContext.Provider>\n )\n}\n","import React, {ComponentType, CSSProperties} from 'react'\nimport {Dashboard} from './containers/Dashboard'\nimport {definePlugin} from 'sanity'\nimport {DashboardConfig, DashboardWidget, LayoutConfig} from './types'\n\nconst strokeStyle: CSSProperties = {\n stroke: 'currentColor',\n strokeWidth: 1.2,\n}\n\nconst DashboardIcon = () => (\n <svg\n data-sanity-icon\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n preserveAspectRatio=\"xMidYMid\"\n width=\"1em\"\n height=\"1em\"\n >\n <path d=\"M19.5 19.5H5.5V5.5H19.5V19.5Z\" style={strokeStyle} />\n <path d=\"M5.5 12.5H19.5\" style={strokeStyle} />\n <path d=\"M14.5 19.5V12.5M10.5 12.5V5.5\" style={strokeStyle} />\n </svg>\n)\n\nexport interface DashboardPluginConfig {\n /**\n * Dashboard tool title\n */\n title?: string\n /**\n * Dashboard tool name (used in url path)\n */\n name?: string\n /**\n * Dashboard tool icon\n */\n icon?: ComponentType\n widgets?: DashboardWidget[]\n\n /**\n * Will be used for widgets that do not define a layout directly.\n */\n defaultLayout?: LayoutConfig\n}\n\nexport const dashboardTool = definePlugin<DashboardPluginConfig>((config = {}) => {\n const pluginConfig: DashboardConfig = {\n layout: config.defaultLayout ?? {},\n widgets: config.widgets ?? [],\n }\n\n const title = config.title ?? 'Dashboard'\n const name = config.name ?? 'dashboard'\n const icon = config.icon ?? DashboardIcon\n\n return {\n name: 'dashboard',\n tools: (prev, context) => {\n return [\n ...prev,\n {\n title,\n name,\n icon,\n component: () => <Dashboard config={pluginConfig} />,\n },\n ]\n },\n }\n})\n","import {ProjectInfo} from './ProjectInfo'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function projectInfoWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'project-info',\n component: ProjectInfo,\n layout: config?.layout ?? {width: 'medium'},\n }\n}\n","import {ProjectUsers} from './ProjectUsers'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function projectUsersWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'project-info',\n component: ProjectUsers,\n layout: config?.layout,\n }\n}\n","import {SanityTutorials} from './SanityTutorials'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function sanityTutorialsWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'sanity-tutorials',\n component: SanityTutorials,\n layout: config?.layout ?? {width: 'full'},\n }\n}\n"],"names":["Root","styled","Card","_templateObject","_taggedTemplateLiteral","Header","_templateObject2","Footer","_templateObject3","Content","Box","_templateObject4","_ref","theme","sanity","media","DashboardWidgetContainer","forwardRef","props","ref","header","children","footer","jsxs","radius","display","jsx","borderBottom","paddingX","paddingY","Heading","size","textOverflow","borderTop","useVersionedClient","useClient","apiVersion","DashboardContext","createContext","widgets","WidgetContainer","config","useContext","layout","useMemo","shadow","width","height","createElement","component","getGroqUrl","projectId","dataset","getManageUrl","concat","NO_EXPERIMENTAL","NO_DATA","ProjectInfo","__experimental_before","data","studioHost","setStudioHost","useState","graphqlApi","setGraphQlApi","versionedClient","useEffect","subscriptions","push","observable","request","uri","subscribe","next","result","host","error","console","method","getGraphQlUrl","statusCode","forEach","s","unsubscribe","assembleTableRows","_a","title","rows","value","apps","filter","item","category","a","length","otherStuff","Object","keys","Fragment","map","widgetConfig","idx","_objectSpread","marginTop","Button","style","mode","tone","text","as","href","role","Stack","space","id","padding","Label","muted","row","url","Grid","columns","Text","weight","test","wordBreak","Code","AvatarWrapper","_templateObject5","ProjectUsers","project","setProject","users","setUsers","setError","userStore","useUserStore","fetchData","useCallback","subscription","pipe","switchMap","_project","from","getUsers","members","mem","_users","_ref2","Array","isArray","sort","userA","userB","membershipA","find","member","membershipB","isRobot","sortUsersByRobotStatus","e","handleRetryFetch","isLoading","onClick","cursor","loading","align","Spinner","user","membership","RobotIcon","imageUrl","src","alt","displayName","DefaultPreview","subtitle","PlayIconBox","_templateObject6","_ref3","color","card","enabled","bg","Flex","_templateObject7","PosterCard","_templateObject8","Poster","img","_templateObject9","Tutorial","posterURL","showPlayIcon","presenterName","presenterSubtitle","flex","sizing","target","rel","position","direction","marginBottom","PlayIcon","justify","opacity","tutorialsProjectConfig","SanityTutorials","templateRepoId","feedItems","setFeedItems","getFeed","urlBuilder","withCredentials","imageUrlBuilder","useDataAdapter","response","items","overflow","feedItem","index","guideOrTutorial","externalLink","presenter","slug","type","_type","current","paddingRight","paddingLeft","minWidth","name","hasVideo","poster","image","_id","DashboardLayout","Container","overflowY","css","_templateObject10","_ref4","_templateObject11","_ref5","_templateObject12","_templateObject15","_templateObject18","_templateObject20","NO_WIDGETS","NO_LAYOUT","WidgetGroup","autoFlow","gap","Dashboard","_ref6","Provider","strokeStyle","stroke","strokeWidth","DashboardIcon","viewBox","fill","xmlns","preserveAspectRatio","d","dashboardTool","definePlugin","arguments","undefined","_b","_c","_d","_e","pluginConfig","defaultLayout","icon","tools","prev","context"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import {ComponentClass} from 'react'
2
+ import {ComponentType} from 'react'
2
3
  import {FunctionComponent} from 'react'
3
4
  import {Plugin as Plugin_2} from 'sanity'
4
5
  import {default as React_2} from 'react'
@@ -9,6 +10,18 @@ export declare interface DashboardConfig {
9
10
  }
10
11
 
11
12
  export declare interface DashboardPluginConfig {
13
+ /**
14
+ * Dashboard tool title
15
+ */
16
+ title?: string
17
+ /**
18
+ * Dashboard tool name (used in url path)
19
+ */
20
+ name?: string
21
+ /**
22
+ * Dashboard tool icon
23
+ */
24
+ icon?: ComponentType
12
25
  widgets?: DashboardWidget[]
13
26
  /**
14
27
  * Will be used for widgets that do not define a layout directly.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/dashboard",
3
- "version": "3.0.0",
3
+ "version": "3.1.1",
4
4
  "description": "Tool for rendering dashboard widgets",
5
5
  "keywords": [
6
6
  "sanity",
@@ -3,7 +3,7 @@ import {Container} from '@sanity/ui'
3
3
 
4
4
  export function DashboardLayout(props: PropsWithChildren<{}>) {
5
5
  return (
6
- <Container width={4} padding={4} sizing="border" style={{minHeight: '100%'}}>
6
+ <Container width={4} padding={4} sizing="border" style={{height: '100%', overflowY: 'auto'}}>
7
7
  {props.children}
8
8
  </Container>
9
9
  )
package/src/plugin.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import React, {CSSProperties} from 'react'
1
+ import React, {ComponentType, CSSProperties} from 'react'
2
2
  import {Dashboard} from './containers/Dashboard'
3
3
  import {definePlugin} from 'sanity'
4
4
  import {DashboardConfig, DashboardWidget, LayoutConfig} from './types'
@@ -25,6 +25,18 @@ const DashboardIcon = () => (
25
25
  )
26
26
 
27
27
  export interface DashboardPluginConfig {
28
+ /**
29
+ * Dashboard tool title
30
+ */
31
+ title?: string
32
+ /**
33
+ * Dashboard tool name (used in url path)
34
+ */
35
+ name?: string
36
+ /**
37
+ * Dashboard tool icon
38
+ */
39
+ icon?: ComponentType
28
40
  widgets?: DashboardWidget[]
29
41
 
30
42
  /**
@@ -39,15 +51,19 @@ export const dashboardTool = definePlugin<DashboardPluginConfig>((config = {}) =
39
51
  widgets: config.widgets ?? [],
40
52
  }
41
53
 
54
+ const title = config.title ?? 'Dashboard'
55
+ const name = config.name ?? 'dashboard'
56
+ const icon = config.icon ?? DashboardIcon
57
+
42
58
  return {
43
59
  name: 'dashboard',
44
60
  tools: (prev, context) => {
45
61
  return [
46
62
  ...prev,
47
63
  {
48
- title: 'Dashboard',
49
- name: 'dashboard',
50
- icon: DashboardIcon,
64
+ title,
65
+ name,
66
+ icon,
51
67
  component: () => <Dashboard config={pluginConfig} />,
52
68
  },
53
69
  ]