diff --git a/ui/cap-react/package.json b/ui/cap-react/package.json index 8b11399c5..f8c9e63da 100644 --- a/ui/cap-react/package.json +++ b/ui/cap-react/package.json @@ -54,7 +54,7 @@ "query-string": "^5.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-formule": "1.1.1", + "react-formule": "1.2.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 6a893a685..8f386c902 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..c8e7177d0 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 = ( @@ -205,10 +223,10 @@ Permissions.propTypes = { const mapStateToProps = state => { return { - schemaName: state.builder.get("formuleState").config.name, - schemaVersion: state.builder.get("formuleState").config.version, permissions: state.builder.get("permissions"), config: state.builder.get("config"), + schemaName: state.builder.getIn(["config", "name"]), + schemaVersion: state.builder.get(["config", "version"]), }; }; 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..36326e7c3 100644 --- a/ui/cap-react/src/antd/drafts/components/Editor/Editor.js +++ b/ui/cap-react/src/antd/drafts/components/Editor/Editor.js @@ -64,9 +64,11 @@ 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} + // FIXME: this is a temporary fix for tab field content not refreshing on isPublished/readonly change + key={mode} /> 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..f9f4143d8 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: { @@ -202,4 +203,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..e470aade7 100644 --- a/ui/cap-react/src/antd/partials/JSONSchemaPreviewer/JSONSchemaPreviewer.js +++ b/ui/cap-react/src/antd/partials/JSONSchemaPreviewer/JSONSchemaPreviewer.js @@ -35,6 +35,7 @@ const JSONSchemaPreviewer = ({ readonlyPreview: true, isPublished: isPublished, }} + isPublished > {children} 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; - } -}