diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 36f9eca55..686fcc812 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: args: ["--config=.flake8"] - repo: https://github.com/pycqa/isort - rev: "5.10.1" + rev: "5.12.0" hooks: - id: isort diff --git a/ui/cap-react/package.json b/ui/cap-react/package.json index e2620134c..d80f627e2 100644 --- a/ui/cap-react/package.json +++ b/ui/cap-react/package.json @@ -57,7 +57,7 @@ "query-string": "^5.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-formule": "1.2.1", + "react-formule": "1.3.0", "react-infinite-scroll-component": "6.1.0", "react-input-mask": "3.0.0-alpha.2", "react-joyride": "^2.5.4", diff --git a/ui/cap-react/src/actions/builder.js b/ui/cap-react/src/actions/builder.js index 4fdb56baf..2bf6e87a0 100644 --- a/ui/cap-react/src/actions/builder.js +++ b/ui/cap-react/src/actions/builder.js @@ -12,6 +12,7 @@ export const SYNCHRONIZE_FORMULE_STATE = "SYNCHRONIZE_FORMULE_STATE"; export const SET_SCHEMA_LOADING = "SET_SCHEMA_LOADING"; export const UPDATE_SCHEMA_CONFIG = "UPDATE_SCHEMA_CONFIG"; +export const UPDATE_SCHEMA_INITIAL_CONFIG = "UPDATE_SCHEMA_INITIAL_CONFIG"; export const UPDATE_NOTIFICATION_BY_INDEX = "UPDATE_NOTIFICATION_BY_INDEX"; export const UPDATE_NOTIFICATIONS = "UPDATE_NOTIFICATIONS"; @@ -35,6 +36,11 @@ export const updateSchemaConfig = config => ({ config, }); +export const updateSchemaInitialConfig = config => ({ + type: UPDATE_SCHEMA_INITIAL_CONFIG, + config, +}); + export const updateNotificationByIndex = data => ({ type: UPDATE_NOTIFICATION_BY_INDEX, payload: data, @@ -158,7 +164,7 @@ export const saveSchemaChanges = () => (dispatch, getState) => { ); // check whether there are changes to the config object const isConfigVersionUpdated = - config.get("version") != state.builder.get("initialConfig").version; + config.get("version") != state.builder.getIn(["initialConfig", "version"]); if (isSchemaUpdated && !isConfigVersionUpdated) { notification.warning({ diff --git a/ui/cap-react/src/antd/admin/components/AdminPanel.js b/ui/cap-react/src/antd/admin/components/AdminPanel.js index 473342b62..f20f53be5 100644 --- a/ui/cap-react/src/antd/admin/components/AdminPanel.js +++ b/ui/cap-react/src/antd/admin/components/AdminPanel.js @@ -46,7 +46,7 @@ const AdminPanel = ({ location, match, getSchema, loading, formuleState }) => { case "notifications": return ; case "permissions": - return ; + return ; default: return ( { const onFinish = content => { let { name, description } = content; - const config = { config: { fullname: name } }; - initFormuleSchemaWithNotifications({ config }, name, description); + initFormuleSchemaWithNotifications({ fullname: name }, name, description); history.push(CMS_NEW); }; diff --git a/ui/cap-react/src/antd/admin/components/Header.js b/ui/cap-react/src/antd/admin/components/Header.js index 7b2276b8e..6feb6794e 100644 --- a/ui/cap-react/src/antd/admin/components/Header.js +++ b/ui/cap-react/src/antd/admin/components/Header.js @@ -59,10 +59,12 @@ const Header = ({ const a = document.createElement("a"); const file = new Blob([fileData], { type: "text/json" }); + const { name, version } = config.toJS(); + const versionStr = version ? `v${version}` : ""; a.href = URL.createObjectURL(file); - a.download = `${config.toJS().name || "cap-schema"}-export-v${ - config.toJS().version - }-${Date.now()}.json`; + a.download = `${ + name || "cap-schema" + }-export${versionStr}-${Date.now()}.json`; a.click(); }; const _renderSchemaPreview = schemaPreviewDisplay => { diff --git a/ui/cap-react/src/antd/admin/containers/Header.js b/ui/cap-react/src/antd/admin/containers/Header.js index b00c79fb3..e4379fe21 100644 --- a/ui/cap-react/src/antd/admin/containers/Header.js +++ b/ui/cap-react/src/antd/admin/containers/Header.js @@ -1,8 +1,5 @@ import { connect } from "react-redux"; -import { - saveSchemaChanges, - updateSchemaConfig, -} from "../../../actions/builder"; +import { saveSchemaChanges } from "../../../actions/builder"; import { pushPath } from "../../../actions/support"; import Header from "../components/Header"; @@ -18,7 +15,6 @@ function mapDispatchToProps(dispatch) { return { saveSchemaChanges: () => dispatch(saveSchemaChanges()), pushPath: path => dispatch(pushPath(path)), - updateSchemaConfig: config => dispatch(updateSchemaConfig(config)), }; } diff --git a/ui/cap-react/src/antd/admin/permissions/Permissions.js b/ui/cap-react/src/antd/admin/permissions/Permissions.js index 0f98b91d1..8a4669dc1 100644 --- a/ui/cap-react/src/antd/admin/permissions/Permissions.js +++ b/ui/cap-react/src/antd/admin/permissions/Permissions.js @@ -29,6 +29,23 @@ import { import { configSchema } from "../utils/schemaSettings"; import { FormuleForm } from "react-formule"; +// Left as documentation +/* + const initialStatePermissions = Map({ + deposit: { + read: { users: [], roles: [] }, + update: { users: [], roles: [] }, + admin: { users: [], roles: [] }, + review: { users: [], roles: [] }, + create: { users: [], roles: [] }, + }, + records: { + read: { users: [], roles: [] }, + review: { users: [], roles: [] }, + }, + }); +*/ + const Permissions = ({ schemaName, schemaVersion, @@ -38,11 +55,12 @@ const Permissions = ({ deleteSchemaPermissions, config, updateSchemaConfig, + isNew, }) => { const [editable, setEditable] = useState(false); const [addEnabled, setAddEnabled] = useState(false); useEffect(() => { - getSchemaPermissions(schemaName, schemaVersion); + !isNew && getSchemaPermissions(schemaName, schemaVersion); }, []); const addSchemaPermissionsToEmail = ( @@ -148,7 +166,7 @@ const Permissions = ({ Here you can manage access to your{" "} - {schemaName} ({schemaVersion}) + {schemaName} {schemaVersion && `(${schemaVersion})`} {" "} collection. You can determine who can perform specific action for both states of your document @@ -205,8 +223,8 @@ Permissions.propTypes = { const mapStateToProps = state => { return { - schemaName: state.builder.get("formuleState").config.name, - schemaVersion: state.builder.get("formuleState").config.version, + schemaName: state.builder.getIn(["config", "name"]), + schemaVersion: state.builder.getIn(["config", "version"]), permissions: state.builder.get("permissions"), config: state.builder.get("config"), }; diff --git a/ui/cap-react/src/antd/admin/utils/index.js b/ui/cap-react/src/antd/admin/utils/index.js index 31c8d9111..fe21a339d 100644 --- a/ui/cap-react/src/antd/admin/utils/index.js +++ b/ui/cap-react/src/antd/admin/utils/index.js @@ -1,7 +1,10 @@ import { initFormuleSchema } from "react-formule"; import { merge } from "lodash-es"; import store from "../../../store/configureStore"; -import { updateSchemaConfig } from "../../../actions/builder"; +import { + updateSchemaConfig, + updateSchemaInitialConfig, +} from "../../../actions/builder"; export const SIZE_OPTIONS = { xsmall: 8, @@ -20,25 +23,18 @@ const NOTIFICATIONS = { }, }; -export const slugify = text => { - return text - .toString() - .toLowerCase() - .replace(/\s+/g, "-") // Replace spaces with - - .replace(/[^\w-]+/g, "") // Remove all non-word chars - .replace(/--+/g, "-") // Replace multiple - with single - - .replace(/^-+/, "") // Trim - from start of text - .replace(/-+$/, ""); // Trim - from end of text -}; - export const initFormuleSchemaWithNotifications = ( data = {}, - name, + title, description ) => { data.config = merge(data.config || {}, NOTIFICATIONS); - initFormuleSchema(data, name, description); - /* eslint no-unused-vars: ["error", { "ignoreRestSiblings": true }]*/ const { deposit_schema, deposit_options, ...configs } = data; + initFormuleSchema( + { schema: deposit_schema, uiSchema: deposit_options, id: configs.name }, + title, + description + ); store.dispatch(updateSchemaConfig(configs)); + store.dispatch(updateSchemaInitialConfig(configs)); }; diff --git a/ui/cap-react/src/antd/drafts/components/Editor/Editor.js b/ui/cap-react/src/antd/drafts/components/Editor/Editor.js index 8a7047aa2..2b6229e0d 100644 --- a/ui/cap-react/src/antd/drafts/components/Editor/Editor.js +++ b/ui/cap-react/src/antd/drafts/components/Editor/Editor.js @@ -64,8 +64,8 @@ const Editor = ({ schema={_schema} uiSchema={schemas.uiSchema || {}} extraErrors={extraErrors || {}} - draftEditor - readonly={mode != "edit" || !canEdit(canAdmin, canUpdate)} + readonly={!canEdit(canAdmin, canUpdate)} + isPublished={mode != "edit"} transformErrors={transformErrors} /> diff --git a/ui/cap-react/src/antd/forms/customFields/services/CAPDeposit.js b/ui/cap-react/src/antd/forms/customFields/services/CAPDeposit.js index a4c5c67cc..5fde2ecfa 100644 --- a/ui/cap-react/src/antd/forms/customFields/services/CAPDeposit.js +++ b/ui/cap-react/src/antd/forms/customFields/services/CAPDeposit.js @@ -2,21 +2,22 @@ import PropTypes from "prop-types"; import { Card, Divider, Modal, Space, Tag, Typography } from "antd"; import { EyeFilled, LinkOutlined } from "@ant-design/icons"; import { useState } from "react"; -import { CodeEditor } from "react-formule"; +import { CodeViewer } from "react-formule"; const CAPDeposit = ({ data }) => { const [showModal, setShowModal] = useState(false); - console.log(JSON.stringify(data, null, 2)); - return ( <> - setShowModal(false)}> - setShowModal(false)} + footer={null} + width={1000} + > + diff --git a/ui/cap-react/src/antd/forms/formuleConfig.js b/ui/cap-react/src/antd/forms/formuleConfig.js index 10c7ea700..a0b806943 100644 --- a/ui/cap-react/src/antd/forms/formuleConfig.js +++ b/ui/cap-react/src/antd/forms/formuleConfig.js @@ -5,6 +5,7 @@ import CernUsers from "./customFields/CernUsers"; import CapFiles from "./customFields/CapFiles"; import IdFetcher from "./customFields/IdFetcher"; import ImportDataField from "./customFields/ImportDataField"; +import SchemaPathSuggester from "./customFields/SchemaPathSuggester"; export const customFieldTypes = { advanced: { @@ -93,7 +94,6 @@ export const customFieldTypes = { properties: {}, }, uiSchema: { - "ui:serfvicesList": ["orcid", "ror", "zenodo"], "ui:servicesList": ["capDeposits"], "ui:field": "idFetcher", }, @@ -202,4 +202,5 @@ export const customFields = { CapFiles: CapFiles, idFetcher: IdFetcher, importData: ImportDataField, + schemaPathSuggester: SchemaPathSuggester, }; diff --git a/ui/cap-react/src/antd/partials/JSONSchemaPreviewer/JSONSchemaPreviewer.js b/ui/cap-react/src/antd/partials/JSONSchemaPreviewer/JSONSchemaPreviewer.js index 5a128d45e..f3a50d11b 100644 --- a/ui/cap-react/src/antd/partials/JSONSchemaPreviewer/JSONSchemaPreviewer.js +++ b/ui/cap-react/src/antd/partials/JSONSchemaPreviewer/JSONSchemaPreviewer.js @@ -2,7 +2,6 @@ import { FormuleForm } from "react-formule"; import PropTypes from "prop-types"; const JSONSchemaPreviewer = ({ - isPublished, schema, uiSchema, children, @@ -10,12 +9,10 @@ const JSONSchemaPreviewer = ({ onChange, onSubmit, formData, - className, }) => { return ( schema && ( {}} onChange={onChange} onSubmit={onSubmit} - formContext={{ - tabView: display === "tabView", - readonlyPreview: true, - isPublished: isPublished, - }} + isPublished > {children} diff --git a/ui/cap-react/src/antd/published/components/Preview.js b/ui/cap-react/src/antd/published/components/Preview.js index 4a07ed10b..86242703c 100644 --- a/ui/cap-react/src/antd/published/components/Preview.js +++ b/ui/cap-react/src/antd/published/components/Preview.js @@ -149,8 +149,6 @@ const Preview = ({ schema={transformSchema(schemas.schema)} schemaType={schemaType} uiSchema={schemas.uiSchema} - isPublished - className={["__PublishedForm__"]} > diff --git a/ui/cap-react/src/reducers/builder.js b/ui/cap-react/src/reducers/builder.js index 95cbcda06..1572379bc 100644 --- a/ui/cap-react/src/reducers/builder.js +++ b/ui/cap-react/src/reducers/builder.js @@ -2,6 +2,7 @@ import { Map, fromJS } from "immutable"; import { UPDATE_SCHEMA_CONFIG, + UPDATE_SCHEMA_INITIAL_CONFIG, UPDATE_NOTIFICATION_BY_INDEX, UPDATE_NOTIFICATIONS, REMOVE_NOTIFICATION, @@ -26,6 +27,8 @@ export default function schemaReducer(state = initialState, action) { return state.set("loading", action.value); case UPDATE_SCHEMA_CONFIG: return state.set("config", fromJS(action.config)); + case UPDATE_SCHEMA_INITIAL_CONFIG: + return state.set("initialConfig", fromJS(action.config)); case UPDATE_NOTIFICATION_BY_INDEX: return state.setIn(action.payload.path, action.payload.value); case UPDATE_NOTIFICATIONS: diff --git a/ui/cap-react/src/style.less b/ui/cap-react/src/style.less index 5fd84c0f7..d9439795a 100644 --- a/ui/cap-react/src/style.less +++ b/ui/cap-react/src/style.less @@ -104,9 +104,3 @@ body, border-radius: 2px; font-family: "Titillium Web"; } - -.__PublishedForm__ { - textarea { - resize: none; - } -} diff --git a/ui/yarn.lock b/ui/yarn.lock index 8ee082509..336c7c663 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -14235,10 +14235,10 @@ react-floater@^0.7.9: prop-types "^15.8.1" tree-changes "^0.9.1" -react-formule@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/react-formule/-/react-formule-1.2.1.tgz#2c48212abfd0ef9a526e71f289c30cc0e0fd710d" - integrity sha512-pSpadIfKQLgw64gIT9QD11p+jlJQjG1djWwE0qkXvnPLBWuIyJ98ys3Pnp0d4+lhMHGd9NV/SjS4iU6hllWnjg== +react-formule@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/react-formule/-/react-formule-1.3.0.tgz#7ee88d794716e828de28201c418cf324e71807c6" + integrity sha512-Evd4d4z8dTWCidgfy8WxDXp7Iw1WpSupMnWPDjJHFZvxdDT1fo0bQ64h4yhhYDEbwnebCjb9UhRtKQFRnDiIKg== dependencies: "@ant-design/pro-layout" "^7.16.4" "@codemirror/lang-json" "^6.0.1"