diff --git a/src/containers/SettingsEditor/FormTemplates/FieldTemplate.tsx b/src/containers/SettingsEditor/FormTemplates/FieldTemplate.tsx
index c2b9e1b10..7da23bddf 100644
--- a/src/containers/SettingsEditor/FormTemplates/FieldTemplate.tsx
+++ b/src/containers/SettingsEditor/FormTemplates/FieldTemplate.tsx
@@ -10,6 +10,7 @@ import { FieldTemplateProps } from '@rjsf/utils'
import { CSS } from 'styled-components/dist/types'
import { matchesFilterKeys } from './searchMatcher'
import { toast } from 'react-toastify'
+import AccessWidget from '../Widgets/AccessWidget'
const arrayStartsWith = (arr1: $Any, arr2: $Any) => {
// return true, if first array starts with second array
@@ -54,8 +55,9 @@ function FieldTemplate(props: FieldTemplateProps) {
}, [section, filterKeys])
// Object fields
+
- if (props.schema.type === 'object') {
+ if (props.schema.type === 'object' && props.schema?.widget !== 'access') {
return (
<>
{divider}
@@ -204,6 +206,19 @@ function FieldTemplate(props: FieldTemplateProps) {
props.id,
)
+
+ let mainWidget = null
+ if (props.schema.widget === 'access') {
+ mainWidget = (
+
+ )
+ } else {
+ mainWidget = props.children
+ }
+
+
+
+
return (
)}
- {props.children}
+
+ {mainWidget}
)
diff --git a/src/containers/SettingsEditor/FormTemplates/ObjectFieldTemplate.tsx b/src/containers/SettingsEditor/FormTemplates/ObjectFieldTemplate.tsx
index 05b596843..3d0bdc999 100644
--- a/src/containers/SettingsEditor/FormTemplates/ObjectFieldTemplate.tsx
+++ b/src/containers/SettingsEditor/FormTemplates/ObjectFieldTemplate.tsx
@@ -21,6 +21,7 @@ const arrayStartsWith = (arr1: $Any, arr2: $Any) => {
return true
}
+
function ObjectFieldTemplate(props: { id: string } & ObjectFieldTemplateProps) {
const [contextMenu] = useCreateContextMenu([])
let className = 'form-object-field'
@@ -78,6 +79,7 @@ function ObjectFieldTemplate(props: { id: string } & ObjectFieldTemplateProps) {
}, [props.properties])
const fields = useMemo(() => {
+
let hiddenFields: $Any[] = []
for (const propName in props?.schema?.properties || {}) {
//@ts-ignore
@@ -96,6 +98,7 @@ function ObjectFieldTemplate(props: { id: string } & ObjectFieldTemplateProps) {
}
}
+
if (props.schema.layout === 'expanded') {
let nameField = null
let otherFields = []
@@ -162,6 +165,7 @@ function ObjectFieldTemplate(props: { id: string } & ObjectFieldTemplateProps) {
// aaand... render
+
if (['compact', 'root', 'expanded'].includes(props.schema.layout)) return fields
const contextMenuModel = useMemo(() => {
diff --git a/src/containers/SettingsEditor/SettingsEditor.sass b/src/containers/SettingsEditor/SettingsEditor.sass
index 4f597d6b8..e66468779 100644
--- a/src/containers/SettingsEditor/SettingsEditor.sass
+++ b/src/containers/SettingsEditor/SettingsEditor.sass
@@ -125,6 +125,7 @@ $field-gap: 8px
.form-inline-field
display: flex
+ min-width: 250px
flex-grow: 1
flex-direction: row
align-items: center
@@ -135,7 +136,6 @@ $field-gap: 8px
.form-inline-field-label
flex-basis: 250px
- min-width: 250px
padding-left: 4px
cursor: pointer
user-select: none
diff --git a/src/containers/SettingsEditor/SettingsEditor.styled.tsx b/src/containers/SettingsEditor/SettingsEditor.styled.tsx
index 6d425760f..e944d93fd 100644
--- a/src/containers/SettingsEditor/SettingsEditor.styled.tsx
+++ b/src/containers/SettingsEditor/SettingsEditor.styled.tsx
@@ -1,6 +1,6 @@
import styled from 'styled-components'
-const FormWrapper = styled.div<{$currentSelection: string}>`
+const FormWrapper = styled.div<{ $currentSelection: string }>`
[data-fieldid='${(props) => props.$currentSelection}'] {
border-radius: 4px;
background-color: rgba(0, 0, 0, 0.2);
@@ -39,4 +39,45 @@ const FormWrapper = styled.div<{$currentSelection: string}>`
}
}
`
-export { FormWrapper }
+
+
+const CodeEditorWrapper = styled.div`
+ position: relative;
+ display: flex;
+ resize: vertical;
+ overflow: auto;
+ flex-direction: column;
+ min-height: 40px;
+ height: 200px;
+ border: 1px solid var(--md-sys-color-outline-variant);
+ border-radius: var(--border-radius-m);
+
+ .wrap {
+ position: relative;
+ top: 0;
+ left: 0;
+ overflow: scroll;
+ }
+ .w-tc-editor {
+ background-color: var(--md-sys-color-surface-container-low);
+ flex-grow: 1;
+ overflow: unset !important;
+ * {
+ background-color: var(--md-sys-color-surface-container-low);
+ font-family: monospace !important;
+ font-size: 12px;
+ }
+ }
+
+ &.error {
+ border: 1px solid var(--md-sys-color-error);
+ }
+
+ &.changed {
+ border: 1px solid var(--md-sys-color-primary);
+ }
+
+`
+
+
+export { FormWrapper, CodeEditorWrapper }
diff --git a/src/containers/SettingsEditor/Widgets/AccessWidget.jsx b/src/containers/SettingsEditor/Widgets/AccessWidget.jsx
new file mode 100644
index 000000000..f2ac666a8
--- /dev/null
+++ b/src/containers/SettingsEditor/Widgets/AccessWidget.jsx
@@ -0,0 +1,202 @@
+import axios from 'axios'
+import styled from 'styled-components'
+
+import { toast } from 'react-toastify'
+import { useState, useEffect, useMemo } from 'react'
+import { updateChangedKeys, parseContext, getDefaultValue } from '../helpers'
+import CodeEditor from '@uiw/react-textarea-code-editor'
+import { CodeEditorWrapper } from '../SettingsEditor.styled'
+import { Button, Dialog } from '@ynput/ayon-react-components'
+
+
+const ShareOption = styled.div`
+ background: #434a56;
+ border-radius: 4px;
+ padding: 8px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+`
+
+const ShareOptionsContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ overflow-y: auto;
+`
+
+
+
+
+const AccessEditorDialog = ({ initialValue, onSubmit, projectName }) => {
+
+ const [shareOptions, setShareOptions] = useState([])
+ const [values, setValues] = useState(initialValue || {})
+
+ useEffect(() => {
+ const fetchShareOptions = async () => {
+ try {
+ const response = await axios.get('/api/share', {params: { project_name: projectName }})
+ const result = [
+ { label: 'Internal users', value: '__everyone__', 'shareType': 'global' },
+ { label: 'Guest users', value: '__guests__', 'shareType': 'global' },
+ ]
+ for (const option of response.data.options) {
+ result.push({ label: option.label, value: option.value, shareType: option.shareType })
+ }
+
+ setShareOptions(result)
+ } catch (error) {
+ console.error('Error fetching share options:', error)
+ toast.error('Failed to fetch share options')
+ }
+ }
+
+ fetchShareOptions()
+ }, [projectName])
+
+
+ const footer = (
+
+
+ )
+
+ return (
+
+ )
+}
+
+
+
+
+const AccessWidget = (props) => {
+ const { path } = parseContext(props)
+ const projectName = props?.formContext?.headerProjectName
+
+ const [value, setValue] = useState(props.formData || {})
+ const [isOpen, setIsOpen] = useState(false)
+
+ const onDialogSubmit = (commitValue) => {
+ console.log("Dialog submitted with value:", commitValue)
+ if (commitValue === null) {
+ setIsOpen(false)
+ return
+ }
+
+ const isChanged = commitValue !== value
+ setValue(commitValue)
+ props.onChange(commitValue)
+ setTimeout(() => {
+ updateChangedKeys(props, isChanged, path)
+ setStatus('unchanged')
+ }, 100)
+ setIsOpen(false)
+ }
+
+
+ const dialogComponent = useMemo(() => {
+ if (!isOpen) return
+ return (
+
+ )
+ }, [value, isOpen, projectName])
+
+
+ return (
+ <>
+ {
+ setIsOpen(true);
+ console.log("Opening access editor")
+ }}
+ label="Edit Access"
+ icon="lock"
+ />
+ {dialogComponent}
+ >
+ )
+}
+
+
+/*
+ const [textValue, setTextValue] = useState('{}')
+ const [status, setStatus] = useState('unchanged')
+
+ useEffect(() => {
+ setTextValue(JSON.stringify(props.formData || {}, null, 2))
+ }, [value])
+
+
+ const onCommit = () => {
+ let commitValue = {}
+ try {
+ commitValue = JSON.parse(textValue)
+ } catch (e) {
+ toast.error("Invalid JSON")
+ setStatus('error')
+ return
+ }
+
+ const isChanged = commitValue !== value
+ setValue(commitValue)
+ props.onChange(commitValue)
+
+ setTimeout(() => {
+ updateChangedKeys(props, isChanged, path)
+ setStatus('unchanged')
+ }, 100)
+ }
+
+
+ return (
+ <>
+
+ {
+ setTextValue(e.target.value)
+ setStatus('changed')
+ }}
+ onBlur={onCommit}
+ />
+
+ >
+ )
+}
+*/
+export default AccessWidget
+
+
diff --git a/src/containers/SettingsEditor/Widgets/TextWidget.tsx b/src/containers/SettingsEditor/Widgets/TextWidget.tsx
index 0c7b9709b..4c6864ecc 100644
--- a/src/containers/SettingsEditor/Widgets/TextWidget.tsx
+++ b/src/containers/SettingsEditor/Widgets/TextWidget.tsx
@@ -1,6 +1,5 @@
import React from 'react'
import CodeEditor from '@uiw/react-textarea-code-editor'
-import styled from 'styled-components'
import { useEffect, useState } from 'react'
import { equiv, getDefaultValue, parseContext, updateChangedKeys } from '../helpers'
import { $Any } from '@types'
@@ -13,41 +12,14 @@ import {
InputTextarea,
} from '@ynput/ayon-react-components'
+import {CodeEditorWrapper} from '../SettingsEditor.styled'
+
type PermissionWidgetProps = {
value: number
setValue: (value: number) => void
}
-const CodeEditorWrapper = styled.div`
- position: relative;
- display: flex;
- resize: vertical;
- overflow: auto;
- flex-direction: column;
- min-height: 40px;
- height: 200px;
- border: 1px solid var(--md-sys-color-outline-variant);
- border-radius: var(--border-radius-m);
-
- .wrap {
- position: relative;
- top: 0;
- left: 0;
- overflow: scroll;
- }
- .w-tc-editor {
- background-color: var(--md-sys-color-surface-container-low);
- flex-grow: 1;
- overflow: unset !important;
- * {
- background-color: var(--md-sys-color-surface-container-low);
- font-family: monospace !important;
- font-size: 12px;
- }
- }
-`
-
const SettingsCodeEditor = (props: $Any) => {
return (