sanity-plugin-mux-input 2.7.0 → 2.8.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/dist/index.d.mts CHANGED
@@ -170,6 +170,13 @@ declare interface PluginConfig extends MuxInputConfig {
170
170
  title?: string
171
171
  icon?: React.ComponentType
172
172
  }
173
+ /**
174
+ * The roles that are allowed to configure the plugin.
175
+ *
176
+ * If not set, all roles will be allowed to configure the plugin.
177
+ * @defaultValue []
178
+ */
179
+ allowedRolesForConfiguration: string[]
173
180
  }
174
181
 
175
182
  declare const SUPPORTED_MUX_LANGUAGES_VALUES: (
package/dist/index.d.ts CHANGED
@@ -170,6 +170,13 @@ declare interface PluginConfig extends MuxInputConfig {
170
170
  title?: string
171
171
  icon?: React.ComponentType
172
172
  }
173
+ /**
174
+ * The roles that are allowed to configure the plugin.
175
+ *
176
+ * If not set, all roles will be allowed to configure the plugin.
177
+ * @defaultValue []
178
+ */
179
+ allowedRolesForConfiguration: string[]
173
180
  }
174
181
 
175
182
  declare const SUPPORTED_MUX_LANGUAGES_VALUES: (
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
19
19
  mod
20
20
  ));
21
21
  Object.defineProperty(exports, "__esModule", { value: !0 });
22
- var sanity = require("sanity"), jsxRuntime = require("react/jsx-runtime"), icons = require("@sanity/icons"), ui = require("@sanity/ui"), React = require("react"), compact = require("lodash/compact.js"), toLower = require("lodash/toLower.js"), trim = require("lodash/trim.js"), uniq = require("lodash/uniq.js"), words = require("lodash/words.js"), styledComponents = require("styled-components"), uuid = require("@sanity/uuid"), rxjs = require("rxjs"), operators = require("rxjs/operators"), suspendReact = require("suspend-react"), MuxPlayer = require("@mux/mux-player-react"), desk = require("sanity/desk"), router = require("sanity/router"), isNumber = require("lodash/isNumber.js"), isString = require("lodash/isString.js"), reactRx = require("react-rx"), useSWR = require("swr"), scrollIntoView = require("scroll-into-view-if-needed"), upchunk = require("@mux/upchunk"), reactIs = require("react-is"), LanguagesList = require("iso-639-1");
22
+ var sanity = require("sanity"), jsxRuntime = require("react/jsx-runtime"), icons = require("@sanity/icons"), ui = require("@sanity/ui"), React = require("react"), compact = require("lodash/compact.js"), toLower = require("lodash/toLower.js"), trim = require("lodash/trim.js"), uniq = require("lodash/uniq.js"), words = require("lodash/words.js"), styledComponents = require("styled-components"), uuid = require("@sanity/uuid"), rxjs = require("rxjs"), operators = require("rxjs/operators"), suspendReact = require("suspend-react"), MuxPlayer = require("@mux/mux-player-react"), router = require("sanity/router"), isNumber = require("lodash/isNumber.js"), isString = require("lodash/isString.js"), reactRx = require("react-rx"), useSWR = require("swr"), scrollIntoView = require("scroll-into-view-if-needed"), upchunk = require("@mux/upchunk"), reactIs = require("react-is"), LanguagesList = require("iso-639-1");
23
23
  function _interopDefaultCompat(e) {
24
24
  return e && typeof e == "object" && "default" in e ? e : { default: e };
25
25
  }
@@ -916,7 +916,7 @@ function VideoPlayer({
916
916
  crossOrigin: "anonymous",
917
917
  metadata: {
918
918
  player_name: "Sanity Admin Dashboard",
919
- player_version: "2.7.0",
919
+ player_version: "2.8.1",
920
920
  page_type: "Preview Player"
921
921
  },
922
922
  audio: isAudio,
@@ -1067,18 +1067,7 @@ function PaneItemPreview(props) {
1067
1067
  function getIconWithFallback(icon, schemaType, defaultIcon) {
1068
1068
  return icon === !1 ? !1 : icon || schemaType && schemaType.icon || defaultIcon || !1;
1069
1069
  }
1070
- function DocumentPreviewInInput(props) {
1071
- const { ChildLink } = desk.usePaneRouter();
1072
- return (linkProps) => /* @__PURE__ */ jsxRuntime.jsx(
1073
- ChildLink,
1074
- {
1075
- childId: props.documentPair.id,
1076
- childParameters: { type: props.documentPair.type },
1077
- children: linkProps.children
1078
- }
1079
- );
1080
- }
1081
- function DocumentPreviewInRool(props) {
1070
+ function DocumentPreviewLink(props) {
1082
1071
  return (linkProps) => /* @__PURE__ */ jsxRuntime.jsx(router.IntentLink, { intent: "edit", params: { id: props.documentPair.id }, children: linkProps.children });
1083
1072
  }
1084
1073
  function DocumentPreview(props) {
@@ -1097,7 +1086,7 @@ function DocumentPreview(props) {
1097
1086
  sanity.PreviewCard,
1098
1087
  {
1099
1088
  __unstable_focusRing: !0,
1100
- as: props.placement === "input" ? DocumentPreviewInInput(props) : DocumentPreviewInRool(props),
1089
+ as: DocumentPreviewLink(props),
1101
1090
  "data-as": "a",
1102
1091
  "data-ui": "PaneItem",
1103
1092
  padding: 2,
@@ -1134,14 +1123,7 @@ const Container = styledComponents.styled(ui.Box)`
1134
1123
  radius: 2,
1135
1124
  shadow: 1,
1136
1125
  style: { overflow: "hidden" },
1137
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(
1138
- DocumentPreview,
1139
- {
1140
- documentPair,
1141
- schemaType,
1142
- placement: props.placement
1143
- }
1144
- ) })
1126
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(DocumentPreview, { documentPair, schemaType }) })
1145
1127
  },
1146
1128
  documentPair.id
1147
1129
  );
@@ -1152,7 +1134,6 @@ function DeleteDialog({
1152
1134
  references,
1153
1135
  referencesLoading,
1154
1136
  cancelDelete,
1155
- placement,
1156
1137
  succeededDeleting
1157
1138
  }) {
1158
1139
  const client = useClient(), [state, setState] = React.useState("checkingReferences"), [deleteOnMux, setDeleteOnMux] = React.useState(!0), toast = ui.useToast();
@@ -1205,14 +1186,7 @@ function DeleteDialog({
1205
1186
  " ",
1206
1187
  "pointing to this video. Remove their references to this file or delete them before proceeding."
1207
1188
  ] }),
1208
- /* @__PURE__ */ jsxRuntime.jsx(
1209
- VideoReferences,
1210
- {
1211
- references,
1212
- isLoaded: !referencesLoading,
1213
- placement
1214
- }
1215
- )
1189
+ /* @__PURE__ */ jsxRuntime.jsx(VideoReferences, { references, isLoaded: !referencesLoading })
1216
1190
  ] }),
1217
1191
  state === "confirm" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1218
1192
  /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { size: 2, children: "Are you sure you want to delete this video?" }),
@@ -1403,7 +1377,6 @@ const AssetInput = (props) => /* @__PURE__ */ jsxRuntime.jsx(FormField$1, { titl
1403
1377
  {
1404
1378
  asset: props.asset,
1405
1379
  cancelDelete: () => setState("idle"),
1406
- placement: props.placement,
1407
1380
  referencesLoading,
1408
1381
  references,
1409
1382
  succeededDeleting: () => {
@@ -1585,14 +1558,7 @@ ${displayInfo.id}`, icon: icons.TagIcon, size: 2 }),
1585
1558
  "aria-labelledby": "references-tab",
1586
1559
  id: "references-panel",
1587
1560
  hidden: tab !== "references",
1588
- children: /* @__PURE__ */ jsxRuntime.jsx(
1589
- VideoReferences,
1590
- {
1591
- references,
1592
- isLoaded: !referencesLoading,
1593
- placement: props.placement
1594
- }
1595
- )
1561
+ children: /* @__PURE__ */ jsxRuntime.jsx(VideoReferences, { references, isLoaded: !referencesLoading })
1596
1562
  }
1597
1563
  )
1598
1564
  ] })
@@ -1820,7 +1786,7 @@ function VideosBrowser({ onSelect }) {
1820
1786
  const { assets, isLoading, searchQuery, setSearchQuery, setSort, sort } = useAssets(), [editedAsset, setEditedAsset] = React.useState(null), freshEditedAsset = React.useMemo(
1821
1787
  () => assets.find((a2) => a2._id === editedAsset?._id) || editedAsset,
1822
1788
  [editedAsset, assets]
1823
- ), placement = onSelect ? "input" : "tool";
1789
+ );
1824
1790
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1825
1791
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { padding: 4, space: 4, style: { minHeight: "50vh" }, children: [
1826
1792
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "space-between", align: "center", children: [
@@ -1836,7 +1802,7 @@ function VideosBrowser({ onSelect }) {
1836
1802
  ),
1837
1803
  /* @__PURE__ */ jsxRuntime.jsx(SelectSortOptions, { setSort, sort })
1838
1804
  ] }),
1839
- placement === "tool" && /* @__PURE__ */ jsxRuntime.jsx(ImportVideosFromMux, {})
1805
+ (onSelect ? "input" : "tool") == "tool" && /* @__PURE__ */ jsxRuntime.jsx(ImportVideosFromMux, {})
1840
1806
  ] }),
1841
1807
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1842
1808
  assets?.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(ui.Label, { muted: !0, children: [
@@ -1868,14 +1834,7 @@ function VideosBrowser({ onSelect }) {
1868
1834
  isLoading && /* @__PURE__ */ jsxRuntime.jsx(SpinnerBox, {}),
1869
1835
  !isLoading && assets.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { marginY: 4, paddingX: 4, paddingY: 6, border: !0, radius: 2, tone: "transparent", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { align: "center", muted: !0, size: 3, children: searchQuery ? `No videos found for "${searchQuery}"` : "No videos in this dataset" }) })
1870
1836
  ] }),
1871
- freshEditedAsset && /* @__PURE__ */ jsxRuntime.jsx(
1872
- VideoDetails,
1873
- {
1874
- closeDialog: () => setEditedAsset(null),
1875
- asset: freshEditedAsset,
1876
- placement
1877
- }
1878
- )
1837
+ freshEditedAsset && /* @__PURE__ */ jsxRuntime.jsx(VideoDetails, { closeDialog: () => setEditedAsset(null), asset: freshEditedAsset })
1879
1838
  ] });
1880
1839
  }
1881
1840
  const StudioTool = () => /* @__PURE__ */ jsxRuntime.jsx(VideosBrowser, {}), DEFAULT_TOOL_CONFIG = {
@@ -2349,9 +2308,12 @@ const InputFallback = () => /* @__PURE__ */ jsxRuntime.jsx("div", { style: { pad
2349
2308
  /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { marginTop: 3, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { align: "center", muted: !0, size: 1, children: "Loading\u2026" }) })
2350
2309
  ] })
2351
2310
  }
2352
- ) });
2311
+ ) }), useAccessControl = (config) => {
2312
+ const user = sanity.useCurrentUser();
2313
+ return { hasConfigAccess: !config?.allowedRolesForConfiguration || user?.roles?.some((role) => config.allowedRolesForConfiguration.includes(role.name)) };
2314
+ };
2353
2315
  function Onboard(props) {
2354
- const { setDialogState } = props, handleOpen = React.useCallback(() => setDialogState("secrets"), [setDialogState]);
2316
+ const { setDialogState } = props, handleOpen = React.useCallback(() => setDialogState("secrets"), [setDialogState]), { hasConfigAccess } = useAccessControl(props.config);
2355
2317
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: 2 }, children: /* @__PURE__ */ jsxRuntime.jsx(
2356
2318
  ui.Card,
2357
2319
  {
@@ -2368,7 +2330,7 @@ function Onboard(props) {
2368
2330
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { justify: "flex-start", align: "center", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Grid, { columns: 1, gap: [2, 3, 4, 4], children: [
2369
2331
  /* @__PURE__ */ jsxRuntime.jsx(ui.Inline, { paddingY: 1, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "32px" }, children: /* @__PURE__ */ jsxRuntime.jsx(MuxLogo, {}) }) }),
2370
2332
  /* @__PURE__ */ jsxRuntime.jsx(ui.Inline, { paddingY: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { size: [0, 1, 2, 2], children: "Upload and preview videos directly from your studio." }) }),
2371
- /* @__PURE__ */ jsxRuntime.jsx(ui.Inline, { paddingY: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { mode: "ghost", icon: icons.PlugIcon, text: "Configure API", onClick: handleOpen }) })
2333
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Inline, { paddingY: 1, children: hasConfigAccess ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { mode: "ghost", icon: icons.PlugIcon, text: "Configure API", onClick: handleOpen }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: [3, 3, 3], radius: 2, shadow: 1, tone: "critical", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "You do not have access to configure the Mux API. Please contact your administrator." }) }) })
2372
2334
  ] }) })
2373
2335
  }
2374
2336
  ) }) });
@@ -2851,7 +2813,7 @@ const FileButton = styledComponents.styled(ui.MenuItem)(({ theme }) => {
2851
2813
  color: white;
2852
2814
  `, isVideoAsset = (asset) => asset._type === "mux.videoAsset";
2853
2815
  function PlayerActionsMenu(props) {
2854
- const { asset, readOnly, dialogState, setDialogState, onChange, onSelect } = props, [open, setOpen] = React.useState(!1), [menuElement, setMenuRef] = React.useState(null), isSigned = React.useMemo(() => getPlaybackPolicy(asset) === "signed", [asset]), onReset = React.useCallback(() => onChange(sanity.PatchEvent.from(sanity.unset([]))), [onChange]);
2816
+ const { asset, readOnly, dialogState, setDialogState, onChange, onSelect } = props, [open, setOpen] = React.useState(!1), [menuElement, setMenuRef] = React.useState(null), isSigned = React.useMemo(() => getPlaybackPolicy(asset) === "signed", [asset]), { hasConfigAccess } = useAccessControl(props.config), onReset = React.useCallback(() => onChange(sanity.PatchEvent.from(sanity.unset([]))), [onChange]);
2855
2817
  return React.useEffect(() => {
2856
2818
  open && dialogState && setOpen(!1);
2857
2819
  }, [dialogState, open]), ui.useClickOutsideEvent(
@@ -2902,15 +2864,17 @@ function PlayerActionsMenu(props) {
2902
2864
  }
2903
2865
  ),
2904
2866
  /* @__PURE__ */ jsxRuntime.jsx(ui.MenuDivider, {}),
2905
- /* @__PURE__ */ jsxRuntime.jsx(
2906
- ui.MenuItem,
2907
- {
2908
- icon: icons.PlugIcon,
2909
- text: "Configure API",
2910
- onClick: () => setDialogState("secrets")
2911
- }
2912
- ),
2913
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuDivider, {}),
2867
+ hasConfigAccess && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2868
+ /* @__PURE__ */ jsxRuntime.jsx(
2869
+ ui.MenuItem,
2870
+ {
2871
+ icon: icons.PlugIcon,
2872
+ text: "Configure API",
2873
+ onClick: () => setDialogState("secrets")
2874
+ }
2875
+ ),
2876
+ /* @__PURE__ */ jsxRuntime.jsx(ui.MenuDivider, {})
2877
+ ] }),
2914
2878
  /* @__PURE__ */ jsxRuntime.jsx(
2915
2879
  ui.MenuItem,
2916
2880
  {
@@ -3517,7 +3481,7 @@ const ctrlKey = 17, cmdKey = 91, UploadCardWithFocusRing = withFocusRing(ui.Card
3517
3481
  ] });
3518
3482
  };
3519
3483
  function UploadPlaceholder(props) {
3520
- const { setDialogState, readOnly, onSelect, hovering, needsSetup } = props, handleBrowse = React.useCallback(() => setDialogState("select-video"), [setDialogState]), handleConfigureApi = React.useCallback(() => setDialogState("secrets"), [setDialogState]);
3484
+ const { setDialogState, readOnly, onSelect, hovering, needsSetup } = props, handleBrowse = React.useCallback(() => setDialogState("select-video"), [setDialogState]), handleConfigureApi = React.useCallback(() => setDialogState("secrets"), [setDialogState]), { hasConfigAccess } = useAccessControl(props.config);
3521
3485
  return /* @__PURE__ */ jsxRuntime.jsx(
3522
3486
  ui.Card,
3523
3487
  {
@@ -3554,7 +3518,7 @@ function UploadPlaceholder(props) {
3554
3518
  }
3555
3519
  ),
3556
3520
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { mode: "bleed", icon: icons.SearchIcon, text: "Select", onClick: handleBrowse }),
3557
- /* @__PURE__ */ jsxRuntime.jsx(
3521
+ hasConfigAccess && /* @__PURE__ */ jsxRuntime.jsx(
3558
3522
  ui.Button,
3559
3523
  {
3560
3524
  padding: 3,
@@ -3775,7 +3739,8 @@ function Uploader(props) {
3775
3739
  setDialogState: props.setDialogState,
3776
3740
  onChange: props.onChange,
3777
3741
  onSelect: handleUpload,
3778
- readOnly: props.readOnly
3742
+ readOnly: props.readOnly,
3743
+ config: props.config
3779
3744
  }
3780
3745
  )
3781
3746
  }
@@ -3788,7 +3753,8 @@ function Uploader(props) {
3788
3753
  onSelect: handleUpload,
3789
3754
  readOnly: !!props.readOnly,
3790
3755
  setDialogState: props.setDialogState,
3791
- needsSetup: props.needsSetup
3756
+ needsSetup: props.needsSetup,
3757
+ config: props.config
3792
3758
  }
3793
3759
  )
3794
3760
  }
@@ -3804,12 +3770,12 @@ function Uploader(props) {
3804
3770
  ] });
3805
3771
  }
3806
3772
  const Input = (props) => {
3807
- const client = useClient(), secretDocumentValues = useSecretsDocumentValues(), assetDocumentValues = useAssetDocumentValues(props.value?.asset), poll = useMuxPolling(props.readOnly ? void 0 : assetDocumentValues?.value || void 0), [dialogState, setDialogState] = useDialogState(), error = secretDocumentValues.error || assetDocumentValues.error || poll.error;
3773
+ const client = useClient(), secretDocumentValues = useSecretsDocumentValues(), assetDocumentValues = useAssetDocumentValues(props.value?.asset), poll = useMuxPolling(props.readOnly ? void 0 : assetDocumentValues?.value || void 0), [dialogState, setDialogState] = useDialogState(), { hasConfigAccess } = useAccessControl(props.config), error = secretDocumentValues.error || assetDocumentValues.error || poll.error;
3808
3774
  if (error)
3809
3775
  throw error;
3810
3776
  const isLoading = secretDocumentValues.isLoading || assetDocumentValues.isLoading;
3811
3777
  return /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundaryCard$1, { schemaType: props.schemaType, children: /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(InputFallback, {}), children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(InputFallback, {}) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3812
- secretDocumentValues.value.needsSetup && !assetDocumentValues.value ? /* @__PURE__ */ jsxRuntime.jsx(Onboard, { setDialogState }) : /* @__PURE__ */ jsxRuntime.jsx(
3778
+ secretDocumentValues.value.needsSetup && !assetDocumentValues.value ? /* @__PURE__ */ jsxRuntime.jsx(Onboard, { setDialogState, config: props.config }) : /* @__PURE__ */ jsxRuntime.jsx(
3813
3779
  Uploader,
3814
3780
  {
3815
3781
  ...props,
@@ -3823,7 +3789,7 @@ const Input = (props) => {
3823
3789
  needsSetup: secretDocumentValues.value.needsSetup
3824
3790
  }
3825
3791
  ),
3826
- dialogState === "secrets" && /* @__PURE__ */ jsxRuntime.jsx(
3792
+ dialogState === "secrets" && hasConfigAccess && /* @__PURE__ */ jsxRuntime.jsx(
3827
3793
  ConfigureApi$1,
3828
3794
  {
3829
3795
  setDialogState,
@@ -3989,7 +3955,7 @@ const muxVideoSchema = {
3989
3955
  ]
3990
3956
  }, muxVideoAsset = {
3991
3957
  name: "mux.videoAsset",
3992
- type: "object",
3958
+ type: "document",
3993
3959
  title: "Video asset",
3994
3960
  fields: [
3995
3961
  {
@@ -4030,7 +3996,8 @@ const muxVideoSchema = {
4030
3996
  max_resolution_tier: "1080p",
4031
3997
  normalize_audio: !1,
4032
3998
  defaultSigned: !1,
4033
- tool: DEFAULT_TOOL_CONFIG
3999
+ tool: DEFAULT_TOOL_CONFIG,
4000
+ allowedRolesForConfiguration: []
4034
4001
  }, muxInput = sanity.definePlugin((userConfig) => {
4035
4002
  const config = { ...defaultConfig, ...userConfig || {} };
4036
4003
  return {