UNPKG

@sanity/desk-tool

Version:

Tool for managing all sorts of content in a structured manner

179 lines (177 loc) • 11.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FormView = FormView; var _hooks = require("@sanity/base/hooks"); var _presence = require("@sanity/base/presence"); var _ui = require("@sanity/ui"); var _afterEditorComponent = _interopRequireDefault(require("all:part:@sanity/desk-tool/after-editor-component")); var _document = _interopRequireDefault(require("part:@sanity/base/datastore/document")); var _schema = _interopRequireDefault(require("part:@sanity/base/schema")); var _documentActionUtils = require("part:@sanity/base/util/document-action-utils"); var _filterFieldsFn = _interopRequireDefault(require("part:@sanity/desk-tool/filter-fields-fn?")); var _formBuilder = require("part:@sanity/form-builder"); var _react = _interopRequireWildcard(require("react")); var _operators = require("rxjs/operators"); var _useDocumentPane2 = require("../../useDocumentPane"); var _Delay = require("../../../../components/Delay"); var _useConditionalToast = require("./useConditionalToast"); var _reactHooks = require("@sanity/react-hooks"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } // @todo: remove the following line when part imports has been removed from this file ///<reference types="@sanity/types/parts" /> var INITIAL_STATE = { filterField: () => true }; var preventDefault = ev => ev.preventDefault(); var noop = () => undefined; function FormView(props) { var _editState$transactio, _editState$transactio3; var hidden = props.hidden, margins = props.margins, granted = props.granted; var _useDocumentPane = (0, _useDocumentPane2.useDocumentPane)(), compareValue = _useDocumentPane.compareValue, documentId = _useDocumentPane.documentId, documentSchema = _useDocumentPane.documentSchema, documentType = _useDocumentPane.documentType, focusPath = _useDocumentPane.focusPath, handleChange = _useDocumentPane.handleChange, handleFocus = _useDocumentPane.handleFocus, historyController = _useDocumentPane.historyController, initialValue = _useDocumentPane.initialValue, historyValue = _useDocumentPane.historyValue, markers = _useDocumentPane.markers, ready = _useDocumentPane.ready, changesOpen = _useDocumentPane.changesOpen; var editState = (0, _reactHooks.useEditState)(documentId, documentType); var value = historyValue || editState.draft || editState.published || initialValue; var presence = (0, _hooks.useDocumentPresence)(documentId, { ignoreLastActiveUpdates: true }); var rev = historyController.revTime; var _useState = (0, _react.useState)(INITIAL_STATE), _useState2 = _slicedToArray(_useState, 2), filterField = _useState2[0].filterField, setFilterField = _useState2[1]; var hasTypeMismatch = value !== null && value._type !== documentSchema.name; var isNonExistent = !value || !value._id; // Create a patch channel for each document ID var patchChannelRef = (0, _react.useRef)(); if (!patchChannelRef.current) { patchChannelRef.current = _formBuilder.FormBuilder.createPatchChannel(); } var readOnly = (0, _hooks.unstable_useConditionalProperty)({ document: value, value, checkProperty: documentSchema.readOnly, checkPropertyKey: 'readOnly' }); var isReadOnly = (0, _react.useMemo)(() => { return !ready || rev !== null || !granted || !(0, _documentActionUtils.isActionEnabled)(documentSchema, 'update') || isNonExistent && !(0, _documentActionUtils.isActionEnabled)(documentSchema, 'create') || readOnly; }, [documentSchema, isNonExistent, granted, ready, rev, readOnly]); (0, _react.useEffect)(() => { if (!_filterFieldsFn.default) return undefined; var sub = _filterFieldsFn.default.subscribe(nextFieldFilter => { setFilterField(nextFieldFilter ? { filterField: nextFieldFilter } : INITIAL_STATE); }); return () => sub.unsubscribe(); }, []); var handleBlur = (0, _react.useCallback)(() => { // do nothing }, []); var isLocked = editState === null || editState === void 0 || (_editState$transactio = editState.transactionSyncLock) === null || _editState$transactio === void 0 ? void 0 : _editState$transactio.enabled; (0, _useConditionalToast.useConditionalToast)({ id: "sync-lock-".concat(documentId), status: 'warning', enabled: isLocked, title: "Syncing document\u2026", description: "Please hold tight while the document is synced. This usually happens right after the document has been published, and it shouldn't take more than a few seconds" }); (0, _react.useEffect)(() => { var sub = _document.default.pair.documentEvents(documentId, documentType).pipe((0, _operators.tap)(event => patchChannelRef.current.receiveEvent(event))).subscribe(); return () => { sub.unsubscribe(); }; }, [documentId, documentType, patchChannelRef]); var hasRev = Boolean(value === null || value === void 0 ? void 0 : value._rev); (0, _react.useEffect)(() => { if (hasRev) { // this is a workaround for an issue that caused the document pushed to withDocument to get // stuck at the first initial value. // This effect is triggered only when the document goes from not having a revision, to getting one // so it will kick in as soon as the document is received from the backend patchChannelRef.current.receiveEvent({ type: 'mutation', mutations: [], document: value }); } // React to changes in hasRev only // eslint-disable-next-line react-hooks/exhaustive-deps }, [hasRev]); var form = (0, _react.useMemo)(() => { var _editState$transactio2; if (hasTypeMismatch) { return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_ui.Text, null, "This document is of type ", /*#__PURE__*/_react.default.createElement("code", null, value === null || value === void 0 ? void 0 : value._type), " and cannot be edited as", ' ', /*#__PURE__*/_react.default.createElement("code", null, documentSchema.name), ".")); } return /*#__PURE__*/_react.default.createElement(_presence.PresenceOverlay, { margins: margins }, /*#__PURE__*/_react.default.createElement(_ui.Box, { as: "form", onSubmit: preventDefault }, ready ? /*#__PURE__*/_react.default.createElement(_formBuilder.FormBuilder, { schema: _schema.default, patchChannel: patchChannelRef.current, value: value, compareValue: compareValue, type: documentSchema, presence: presence, filterField: filterField, readOnly: isReadOnly || (editState === null || editState === void 0 || (_editState$transactio2 = editState.transactionSyncLock) === null || _editState$transactio2 === void 0 ? void 0 : _editState$transactio2.enabled), onBlur: handleBlur, onFocus: handleFocus, focusPath: focusPath, onChange: isReadOnly ? noop : handleChange, markers: markers, changesOpen: changesOpen }) : /*#__PURE__*/_react.default.createElement(_Delay.Delay, { ms: 300 }, /*#__PURE__*/_react.default.createElement(_ui.Flex, { align: "center", direction: "column", height: "fill", justify: "center" }, /*#__PURE__*/_react.default.createElement(_ui.Spinner, { muted: true }), /*#__PURE__*/_react.default.createElement(_ui.Box, { marginTop: 3 }, /*#__PURE__*/_react.default.createElement(_ui.Text, { align: "center", muted: true, size: 1 }, "Loading document")))))); }, [hasTypeMismatch, margins, ready, value, compareValue, documentSchema, presence, filterField, isReadOnly, editState === null || editState === void 0 || (_editState$transactio3 = editState.transactionSyncLock) === null || _editState$transactio3 === void 0 ? void 0 : _editState$transactio3.enabled, handleBlur, handleFocus, focusPath, handleChange, markers, changesOpen]); var after = (0, _react.useMemo)(() => Array.isArray(_afterEditorComponent.default) && _afterEditorComponent.default.map((AfterEditorComponent, idx) => /*#__PURE__*/_react.default.createElement(AfterEditorComponent, { key: String(idx), documentId: documentId })), [documentId]); return /*#__PURE__*/_react.default.createElement(_ui.Container, { hidden: hidden, paddingX: 4, paddingTop: 5, paddingBottom: 9, sizing: "border", width: 1 }, form, after); }