@sanity/desk-tool
Version:
Tool for managing all sorts of content in a structured manner
179 lines (177 loc) • 11.2 kB
JavaScript
"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);
}