Merge branch 'dev'
This commit is contained in:
commit
0375ec0714
@ -217,9 +217,11 @@ export default function SearchModal({
|
|||||||
setAddSuccess('')
|
setAddSuccess('')
|
||||||
setAdding(true)
|
setAdding(true)
|
||||||
try {
|
try {
|
||||||
|
// If advanced is not checked, or if advanced is checked but parentId is not set (root selected), use rootUserId as parentUserId
|
||||||
|
const effectiveParentId = (!advanced || !parentId) ? rootUserId : parentId;
|
||||||
const data = await addUserToMatrix({
|
const data = await addUserToMatrix({
|
||||||
childUserId: selected.userId,
|
childUserId: selected.userId,
|
||||||
parentUserId: advanced ? parentId : undefined,
|
parentUserId: effectiveParentId,
|
||||||
forceParentFallback: forceFallback,
|
forceParentFallback: forceFallback,
|
||||||
rootUserId,
|
rootUserId,
|
||||||
matrixId,
|
matrixId,
|
||||||
|
|||||||
@ -5,19 +5,24 @@ export type CreateMatrixResult = {
|
|||||||
message?: string
|
message?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function createMatrix(params: {
|
export async function createMatrix(params: {
|
||||||
token: string
|
token: string
|
||||||
name: string
|
name: string
|
||||||
email: string
|
email: string
|
||||||
|
depth?: number
|
||||||
force?: boolean
|
force?: boolean
|
||||||
baseUrl?: string
|
baseUrl?: string
|
||||||
}): Promise<CreateMatrixResult> {
|
}): Promise<CreateMatrixResult> {
|
||||||
const { token, name, email, force = false, baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL || '' } = params
|
const { token, name, email, depth, force = false, baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL || '' } = params
|
||||||
if (!token) return { ok: false, status: 401, message: 'Missing token' }
|
if (!token) return { ok: false, status: 401, message: 'Missing token' }
|
||||||
|
|
||||||
const url = new URL(`${baseUrl}/api/matrix/create`)
|
const url = new URL(`${baseUrl}/api/matrix/create`)
|
||||||
url.searchParams.set('name', name)
|
url.searchParams.set('name', name)
|
||||||
url.searchParams.set('email', email)
|
url.searchParams.set('email', email)
|
||||||
|
if (typeof depth === 'number' && Number.isFinite(depth)) {
|
||||||
|
url.searchParams.set('depth', String(depth))
|
||||||
|
}
|
||||||
if (force) url.searchParams.set('force', 'true')
|
if (force) url.searchParams.set('force', 'true')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -57,6 +57,7 @@ export default function MatrixManagementPage() {
|
|||||||
const [createName, setCreateName] = useState('')
|
const [createName, setCreateName] = useState('')
|
||||||
const [createEmail, setCreateEmail] = useState('')
|
const [createEmail, setCreateEmail] = useState('')
|
||||||
const [formError, setFormError] = useState<string>('')
|
const [formError, setFormError] = useState<string>('')
|
||||||
|
const [createDepth, setCreateDepth] = useState<number>(5)
|
||||||
|
|
||||||
const [createLoading, setCreateLoading] = useState(false)
|
const [createLoading, setCreateLoading] = useState(false)
|
||||||
const [forcePrompt, setForcePrompt] = useState<{ name: string; email: string } | null>(null)
|
const [forcePrompt, setForcePrompt] = useState<{ name: string; email: string } | null>(null)
|
||||||
@ -120,6 +121,7 @@ export default function MatrixManagementPage() {
|
|||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
setCreateName('')
|
setCreateName('')
|
||||||
setCreateEmail('')
|
setCreateEmail('')
|
||||||
|
setCreateDepth(5)
|
||||||
setFormError('')
|
setFormError('')
|
||||||
setForcePrompt(null)
|
setForcePrompt(null)
|
||||||
setCreateSuccess(null)
|
setCreateSuccess(null)
|
||||||
@ -132,6 +134,7 @@ export default function MatrixManagementPage() {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const name = createName.trim()
|
const name = createName.trim()
|
||||||
const email = createEmail.trim()
|
const email = createEmail.trim()
|
||||||
|
const depth = Number(createDepth)
|
||||||
setFormError('')
|
setFormError('')
|
||||||
setCreateSuccess(null)
|
setCreateSuccess(null)
|
||||||
setForcePrompt(null)
|
setForcePrompt(null)
|
||||||
@ -148,10 +151,14 @@ export default function MatrixManagementPage() {
|
|||||||
setFormError('Not authenticated. Please log in again.')
|
setFormError('Not authenticated. Please log in again.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (!Number.isFinite(depth) || depth < 1 || depth > 20) {
|
||||||
|
setFormError('Please provide a valid matrix depth (1-20).')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
setCreateLoading(true)
|
setCreateLoading(true)
|
||||||
try {
|
try {
|
||||||
const res = await createMatrix({ token, name, email })
|
const res = await createMatrix({ token, name, email, depth })
|
||||||
console.log('🧱 MatrixManagement: create result ->', res.status, res.body)
|
console.log('🧱 MatrixManagement: create result ->', res.status, res.body)
|
||||||
if (res.ok && res.body?.success) {
|
if (res.ok && res.body?.success) {
|
||||||
const createdName = res.body?.data?.name || name
|
const createdName = res.body?.data?.name || name
|
||||||
@ -160,6 +167,7 @@ export default function MatrixManagementPage() {
|
|||||||
await loadStats()
|
await loadStats()
|
||||||
setCreateName('')
|
setCreateName('')
|
||||||
setCreateEmail('')
|
setCreateEmail('')
|
||||||
|
setCreateDepth(5)
|
||||||
} else if (res.status === 409) {
|
} else if (res.status === 409) {
|
||||||
setForcePrompt({ name, email })
|
setForcePrompt({ name, email })
|
||||||
} else {
|
} else {
|
||||||
@ -355,7 +363,7 @@ export default function MatrixManagementPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="mt-2 flex flex-wrap gap-2 text-xs">
|
<div className="mt-2 flex flex-wrap gap-2 text-xs">
|
||||||
<span className={`inline-flex items-center rounded-full px-2 py-0.5 border ${m.status==='inactive'?'border-gray-200 bg-gray-50 text-gray-500':'border-blue-200 bg-blue-50 text-blue-900'}`}>
|
<span className={`inline-flex items-center rounded-full px-2 py-0.5 border ${m.status==='inactive'?'border-gray-200 bg-gray-50 text-gray-500':'border-blue-200 bg-blue-50 text-blue-900'}`}>
|
||||||
Policy: {(!m.policyMaxDepth || m.policyMaxDepth <= 0) ? 'Unlimited' : m.policyMaxDepth}
|
Depth: {(!m.policyMaxDepth || m.policyMaxDepth <= 0) ? 'Unlimited' : m.policyMaxDepth}
|
||||||
</span>
|
</span>
|
||||||
<span className={`inline-flex items-center rounded-full px-2 py-0.5 border ${m.status==='inactive'?'border-gray-200 bg-gray-50 text-gray-500':'border-gray-200 bg-gray-100 text-gray-800'}`}>
|
<span className={`inline-flex items-center rounded-full px-2 py-0.5 border ${m.status==='inactive'?'border-gray-200 bg-gray-50 text-gray-500':'border-gray-200 bg-gray-100 text-gray-800'}`}>
|
||||||
Root: unlimited immediate children (sequential), non-root: 5 children (positions 1–5)
|
Root: unlimited immediate children (sequential), non-root: 5 children (positions 1–5)
|
||||||
@ -495,6 +503,19 @@ export default function MatrixManagementPage() {
|
|||||||
placeholder="owner@example.com"
|
placeholder="owner@example.com"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-blue-900 mb-1">Matrix Depth</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min={1}
|
||||||
|
max={20}
|
||||||
|
value={createDepth}
|
||||||
|
onChange={e => setCreateDepth(Number(e.target.value))}
|
||||||
|
disabled={createLoading}
|
||||||
|
className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm focus:ring-2 focus:ring-blue-900 focus:border-transparent disabled:bg-gray-100"
|
||||||
|
placeholder="e.g., 5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{formError && (
|
{formError && (
|
||||||
<div className="rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
|
<div className="rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user