aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2020-09-27 09:50:23 -0400
committerbobzel <zzzman@gmail.com>2020-09-27 09:50:23 -0400
commitf015bdbbb4c5b9fcf5983ccf593c9405d1303666 (patch)
tree495102510bbf035c01b87c8423ed93b344dc60c9 /src
parentb76e05d530eff780740d8b3cd15cb2ef748719d2 (diff)
parent3f644b65e9ade29acae92f768ef8c322297ce362 (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts4
-rw-r--r--src/client/util/InteractionUtils.tsx45
-rw-r--r--src/client/util/SharingManager.scss2
-rw-r--r--src/client/util/SharingManager.tsx2
-rw-r--r--src/client/views/GestureOverlay.tsx57
-rw-r--r--src/client/views/InkingStroke.tsx11
-rw-r--r--src/client/views/PropertiesView.scss27
-rw-r--r--src/client/views/PropertiesView.tsx5
-rw-r--r--src/fields/Doc.ts4
-rw-r--r--src/fields/util.ts14
10 files changed, 67 insertions, 104 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 2de1090a2..7c420fb90 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -603,7 +603,7 @@ export namespace Docs {
viewDoc.type !== DocumentType.LINK && DocUtils.MakeLinkToActiveAudio(viewDoc);
viewDoc["acl-Public"] = dataDoc["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add;
- viewDoc["acl-Override"] = dataDoc["acl-Override"] = "unset";
+ viewDoc["acl-Override"] = dataDoc["acl-Override"] = "None";
return Doc.assign(viewDoc, delegateProps, true);
}
@@ -749,7 +749,7 @@ export namespace Docs {
I.rotation = 0;
I.data = new InkField(points);
I["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add;
- I["acl-Override"] = "unset";
+ I["acl-Override"] = "None";
return I;
}
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index 4a203d41f..f58277717 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -229,7 +229,7 @@ export namespace InteractionUtils {
export function makePolygon(shape: string, points: { X: number, Y: number }[]) {
if (points.length > 1 && points[points.length - 1].X === points[0].X && points[points.length - 1].Y + 1 === points[0].Y) {
//pointer is up (first and last points are the same)
- if (shape === "arrow" || shape === "line") {
+ if (shape === "arrow" || shape === "line" || shape === "circle") {
//if arrow or line, the two end points should be the starting and the ending point
var left = points[0].X;
var top = points[0].Y;
@@ -251,7 +251,7 @@ export namespace InteractionUtils {
left = points[0].X;
bottom = points[points.length - 1].Y;
top = points[0].Y;
- if (shape !== "arrow" && shape !== "line") {
+ if (shape !== "arrow" && shape !== "line" && shape !== "circle") {
//switch left/right and top/bottom if needed
if (left > right) {
const temp = right;
@@ -299,50 +299,34 @@ export namespace InteractionUtils {
return points;
case "circle":
- // const centerX = (right + left) / 2;
- // const centerY = (bottom + top) / 2;
- // const radius = bottom - centerY;
-
- // for (var y = top; y < bottom; y++) {
- // const x = Math.sqrt(Math.pow(radius, 2) - (Math.pow((y - centerY), 2))) + centerX;
- // points.push({ X: x, Y: y });
- // }
- // for (var y = bottom; y > top; y--) {
- // const x = Math.sqrt(Math.pow(radius, 2) - (Math.pow((y - centerY), 2))) + centerX;
- // const newX = centerX - (x - centerX);
- // points.push({ X: newX, Y: y });
- // }
- // points.push({ X: Math.sqrt(Math.pow(radius, 2) - (Math.pow((top - centerY), 2))) + centerX, Y: top });
- const centerX = (right + left) / 2;
- const centerY = (bottom + top) / 2;
- if ((bottom - centerY) < (right - centerX)) {
- const radius = bottom - centerY;
- for (var y = top; y < bottom; y++) {
+
+
+ const centerX = (Math.max(left, right) + Math.min(left, right)) / 2;
+ const centerY = (Math.max(top, bottom) + Math.min(top, bottom)) / 2;
+ const radius = Math.max(centerX - Math.min(left, right), centerY - Math.min(top, bottom));
+ if (centerX - Math.min(left, right) < centerY - Math.min(top, bottom)) {
+ for (var y = Math.min(top, bottom); y < Math.max(top, bottom); y++) {
const x = Math.sqrt(Math.pow(radius, 2) - (Math.pow((y - centerY), 2))) + centerX;
points.push({ X: x, Y: y });
}
- for (var y = bottom; y > top; y--) {
+ for (var y = Math.max(top, bottom); y > Math.min(top, bottom); y--) {
const x = Math.sqrt(Math.pow(radius, 2) - (Math.pow((y - centerY), 2))) + centerX;
const newX = centerX - (x - centerX);
points.push({ X: newX, Y: y });
}
- points.push({ X: Math.sqrt(Math.pow(radius, 2) - (Math.pow((top - centerY), 2))) + centerX, Y: top });
+ points.push({ X: Math.sqrt(Math.pow(radius, 2) - (Math.pow((Math.min(top, bottom) - centerY), 2))) + centerX, Y: Math.min(top, bottom) });
} else {
- //right = bottom
- //left = top
- const radius = right - centerX;
- for (var x = left; x < right; x++) {
+ for (var x = Math.min(left, right); x < Math.max(left, right); x++) {
const y = Math.sqrt(Math.pow(radius, 2) - (Math.pow((x - centerX), 2))) + centerY;
points.push({ X: x, Y: y });
}
- for (var x = right; x > left; x--) {
+ for (var x = Math.max(left, right); x > Math.min(left, right); x--) {
const y = Math.sqrt(Math.pow(radius, 2) - (Math.pow((x - centerX), 2))) + centerY;
const newY = centerY - (y - centerY);
points.push({ X: x, Y: newY });
}
- points.push({ X: left, Y: Math.sqrt(Math.pow(radius, 2) - (Math.pow((left - centerX), 2))) + centerY });
-
+ points.push({ X: Math.min(left, right), Y: Math.sqrt(Math.pow(radius, 2) - (Math.pow((Math.min(left, right) - centerX), 2))) + centerY });
}
return points;
@@ -365,7 +349,6 @@ export namespace InteractionUtils {
// points.push({ X: x2, Y: y2 });
// return points;
case "line":
-
points.push({ X: left, Y: top });
points.push({ X: right, Y: bottom });
return points;
diff --git a/src/client/util/SharingManager.scss b/src/client/util/SharingManager.scss
index 06458827a..54e3f45bc 100644
--- a/src/client/util/SharingManager.scss
+++ b/src/client/util/SharingManager.scss
@@ -40,7 +40,7 @@
.permissions-select {
z-index: 1;
- margin-left: -100;
+ margin-left: -115;
border: none;
outline: none;
text-align: justify; // for Edge
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 4f2676728..2c9620b02 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -289,7 +289,7 @@ export class SharingManager extends React.Component<{}> {
private sharingOptions(uniform: boolean, override?: boolean) {
const dropdownValues: string[] = Object.values(SharingPermissions);
if (!uniform) dropdownValues.unshift("-multiple-");
- if (override) dropdownValues.unshift("unset");
+ if (override) dropdownValues.unshift("None");
return dropdownValues.filter(permission => permission !== SharingPermissions.View).map(permission =>
(
<option key={permission} value={permission}>
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 6af3a40cf..97dfb7c50 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -695,7 +695,7 @@ export class GestureOverlay extends Touchable {
left = this._points[0].X;
bottom = this._points[this._points.length - 2].Y;
top = this._points[0].Y;
- if (shape !== "arrow" && shape !== "line") {
+ if (shape !== "arrow" && shape !== "line" && shape !== "circle") {
if (left > right) {
const temp = right;
right = left;
@@ -754,65 +754,38 @@ export class GestureOverlay extends Touchable {
break;
case "circle":
- // const centerX = (right + left) / 2;
- // const centerY = (bottom + top) / 2;
- // const radius = bottom - centerY;
-
-
- // for (var y = top; y < bottom; y++) {
- // const x = Math.sqrt(Math.pow(radius, 2) - (Math.pow((y - centerY), 2))) + centerX;
- // this._points.push({ X: x, Y: y });
- // }
- // for (var y = bottom; y > top; y--) {
- // const x = Math.sqrt(Math.pow(radius, 2) - (Math.pow((y - centerY), 2))) + centerX;
- // const newX = centerX - (x - centerX);
- // this._points.push({ X: newX, Y: y });
- // }
- // this._points.push({ X: Math.sqrt(Math.pow(radius, 2) - (Math.pow((top - centerY), 2))) + centerX, Y: top });
- // this._points.push({ X: Math.sqrt(Math.pow(radius, 2) - (Math.pow((top - centerY), 2))) + centerX, Y: top - 1 });
-
- const centerX = (right + left) / 2;
- const centerY = (bottom + top) / 2;
- if ((bottom - centerY) < (right - centerX)) {
- const radius = bottom - centerY;
- for (var y = top; y < bottom; y++) {
+
+ const centerX = (Math.max(left, right) + Math.min(left, right)) / 2;
+ const centerY = (Math.max(top, bottom) + Math.min(top, bottom)) / 2;
+ const radius = Math.max(centerX - Math.min(left, right), centerY - Math.min(top, bottom));
+ if (centerX - Math.min(left, right) < centerY - Math.min(top, bottom)) {
+ for (var y = Math.min(top, bottom); y < Math.max(top, bottom); y++) {
const x = Math.sqrt(Math.pow(radius, 2) - (Math.pow((y - centerY), 2))) + centerX;
this._points.push({ X: x, Y: y });
}
- for (var y = bottom; y > top; y--) {
+ for (var y = Math.max(top, bottom); y > Math.min(top, bottom); y--) {
const x = Math.sqrt(Math.pow(radius, 2) - (Math.pow((y - centerY), 2))) + centerX;
const newX = centerX - (x - centerX);
this._points.push({ X: newX, Y: y });
}
- this._points.push({ X: Math.sqrt(Math.pow(radius, 2) - (Math.pow((top - centerY), 2))) + centerX, Y: top });
- this._points.push({ X: Math.sqrt(Math.pow(radius, 2) - (Math.pow((top - centerY), 2))) + centerX, Y: top - 1 });
+ this._points.push({ X: Math.sqrt(Math.pow(radius, 2) - (Math.pow((Math.min(top, bottom) - centerY), 2))) + centerX, Y: Math.min(top, bottom) });
+ this._points.push({ X: Math.sqrt(Math.pow(radius, 2) - (Math.pow((Math.min(top, bottom) - centerY), 2))) + centerX, Y: Math.min(top, bottom) - 1 });
+
} else {
- //right = bottom
- //left = top
- const radius = right - centerX;
- for (var x = left; x < right; x++) {
+ for (var x = Math.min(left, right); x < Math.max(left, right); x++) {
const y = Math.sqrt(Math.pow(radius, 2) - (Math.pow((x - centerX), 2))) + centerY;
this._points.push({ X: x, Y: y });
}
- for (var x = right; x > left; x--) {
+ for (var x = Math.max(left, right); x > Math.min(left, right); x--) {
const y = Math.sqrt(Math.pow(radius, 2) - (Math.pow((x - centerX), 2))) + centerY;
const newY = centerY - (y - centerY);
this._points.push({ X: x, Y: newY });
}
- this._points.push({ X: left, Y: Math.sqrt(Math.pow(radius, 2) - (Math.pow((left - centerX), 2))) + centerY });
- this._points.push({ X: left, Y: (Math.sqrt(Math.pow(radius, 2) - (Math.pow((left - centerX), 2))) + centerY) - 1 });
-
+ this._points.push({ X: Math.min(left, right), Y: Math.sqrt(Math.pow(radius, 2) - (Math.pow((Math.min(left, right) - centerX), 2))) + centerY });
+ this._points.push({ X: Math.min(left, right), Y: Math.sqrt(Math.pow(radius, 2) - (Math.pow((Math.min(left, right) - centerX), 2))) + centerY - 1 });
}
-
-
-
-
-
-
-
-
break;
case "line":
if (Math.abs(firstx - lastx) < 20) {
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index da98eca73..186406424 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -47,6 +47,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
private _controlNum = 0;
@action
onControlDown = (e: React.PointerEvent, i: number): void => {
+ //TODO:renew points before controlling
setupMoveUpEvents(this, e, this.onControlMove, this.onControlup, (e) => { });
this._controlUndo = UndoManager.StartBatch("DocDecs set radius");
this._prevX = e.clientX;
@@ -160,20 +161,20 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
const addpoints = apoints.map((pts, i) =>
<svg height="10" width="10" key={`add${i}`}>
- <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={dotsize} stroke="invisible" strokeWidth={String(Number(dotsize) / 2)} fill="invisible"
+ <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={strokeWidth / 2} stroke="invisible" strokeWidth={String(Number(dotsize) / 2)} fill="invisible"
onPointerDown={(e) => { formatInstance.addPoints(pts.X, pts.Y, apoints, i, controlPoints); }} pointerEvents="all" cursor="all-scroll"
/>
</svg>);
const controls = controlPoints.map((pts, i) =>
<svg height="10" width="10" key={`ctrl${i}`}>
- <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={dotsize} stroke="black" strokeWidth={String(Number(dotsize) / 2)} fill="red"
+ <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={strokeWidth / 2} stroke="black" strokeWidth={String(Number(dotsize) / 2)} fill="red"
onPointerDown={(e) => { this.changeCurrPoint(pts.I); this.onControlDown(e, pts.I); }} pointerEvents="all" cursor="all-scroll"
/>
</svg>);
const handles = handlePoints.map((pts, i) =>
<svg height="10" width="10" key={`hdl${i}`}>
- <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={dotsize} stroke="black" strokeWidth={String(Number(dotsize) / 2)} fill="green"
+ <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={strokeWidth / 2} stroke="black" strokeWidth={String(Number(dotsize) / 2)} fill="green"
onPointerDown={(e) => this.onControlDown(e, pts.I)} pointerEvents="all" cursor="all-scroll" display={(pts.dot1 === formatInstance._currPoint || pts.dot2 === formatInstance._currPoint) ? "inherit" : "none"} />
</svg>);
const handleLines = handleLine.map((pts, i) =>
@@ -189,8 +190,8 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
return (
<svg className="inkingStroke"
- width={width}
- height={height}
+ width={Math.max(width, height)}
+ height={Math.max(width, height)}
style={{
pointerEvents: this.props.Document.isInkMask ? "all" : "none",
transform: this.props.Document.isInkMask ? `translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss
index e5f9e0417..47d8aacea 100644
--- a/src/client/views/PropertiesView.scss
+++ b/src/client/views/PropertiesView.scss
@@ -246,15 +246,20 @@
}
}
- .expansion-button-icon {
- width: 11px;
- height: 11px;
- color: black;
- margin-left: 27px;
+ .expansion-button {
+ margin-left: -22.5;
+ margin: 3;
- &:hover {
- color: rgb(131, 131, 131);
- cursor: pointer;
+ .expansion-button-icon {
+ width: 11px;
+ height: 11px;
+ color: black;
+ margin-left: 27px;
+
+ &:hover {
+ color: rgb(131, 131, 131);
+ cursor: pointer;
+ }
}
}
@@ -305,9 +310,9 @@
.permissions-select {
border: none;
background-color: inherit;
- width: 75px;
- //text-align: justify; // for Edge
- //text-align-last: end;
+ width: 87px;
+ text-align: justify; // for Edge
+ text-align-last: end;
&:hover {
cursor: pointer;
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 9209cc21a..59358ce40 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -320,6 +320,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
getPermissionsSelect(user: string, permission: string) {
const dropdownValues: string[] = Object.values(SharingPermissions);
if (permission === "-multiple-") dropdownValues.unshift(permission);
+ if (user === "Override") dropdownValues.unshift("None");
return <select className="permissions-select"
value={permission}
onChange={e => this.changePermissions(e, user)}>
@@ -380,7 +381,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
*/
@computed get sharingTable() {
const AclMap = new Map<symbol, string>([
- [AclUnset, "unset"],
+ [AclUnset, "None"],
[AclPrivate, SharingPermissions.None],
[AclReadonly, SharingPermissions.View],
[AclAddonly, SharingPermissions.Add],
@@ -424,7 +425,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const ownerSame = Doc.CurrentUserEmail !== target.author && docs.filter(doc => doc).every(doc => doc.author === docs[0].author);
// shifts the current user, owner, public to the top of the doc.
- tableEntries.unshift(this.sharingItem("Override", showAdmin, docs.filter(doc => doc).every(doc => doc["acl-Override"] === docs[0]["acl-Override"]) ? (AclMap.get(target[AclSym]?.["acl-Override"]) || "unset") : "-multiple-"));
+ tableEntries.unshift(this.sharingItem("Override", showAdmin, docs.filter(doc => doc).every(doc => doc["acl-Override"] === docs[0]["acl-Override"]) ? (AclMap.get(target[AclSym]?.["acl-Override"]) || "None") : "-multiple-"));
tableEntries.unshift(this.sharingItem("Public", showAdmin, docs.filter(doc => doc).every(doc => doc["acl-Public"] === docs[0]["acl-Public"]) ? (AclMap.get(target[AclSym]?.["acl-Public"]) || SharingPermissions.None) : "-multiple-"));
tableEntries.unshift(this.sharingItem("Me", showAdmin, docs.filter(doc => doc).every(doc => doc.author === Doc.CurrentUserEmail) ? "Owner" : effectiveAcls.every(acl => acl === effectiveAcls[0]) ? AclMap.get(effectiveAcls[0])! : "-multiple-", !ownerSame));
if (ownerSame) tableEntries.unshift(this.sharingItem(StrCast(target.author), showAdmin, "Owner"));
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 205831153..a4cf0a826 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -113,7 +113,7 @@ export const UpdatingFromServer = Symbol("UpdatingFromServer");
export const CachedUpdates = Symbol("Cached updates");
const AclMap = new Map<string, symbol>([
- ["unset", AclUnset],
+ ["None", AclUnset],
[SharingPermissions.None, AclPrivate],
[SharingPermissions.View, AclReadonly],
[SharingPermissions.Add, AclAddonly],
@@ -124,7 +124,7 @@ const AclMap = new Map<string, symbol>([
export function fetchProto(doc: Doc) {
const permissions: { [key: string]: symbol } = {};
- Object.keys(doc).filter(key => key.startsWith("acl")).forEach(key => permissions[key] = AclMap.get(StrCast(doc[key]))!);
+ Object.keys(doc).filter(key => key.startsWith("acl") && (permissions[key] = AclMap.get(StrCast(doc[key]))!));
if (Object.keys(permissions).length) doc[AclSym] = permissions;
diff --git a/src/fields/util.ts b/src/fields/util.ts
index fa1c47055..989166bf8 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -173,11 +173,6 @@ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number,
// if the acl is being overriden or the property being modified is one of the playground fields (which can be freely modified)
if (_overrideAcl || (in_prop && DocServer.PlaygroundFields?.includes(in_prop.toString()))) return AclEdit;
- // if there's an overriding acl set through the properties panel or sharing menu, that's what's returned.
- // if it's unset, it just goes ahead
- const override = target[AclSym]["acl-Override"];
- if (override !== AclUnset && override !== undefined) return target[AclSym]["acl-Override"];
-
let effectiveAcl = AclPrivate;
const HierarchyMapping = new Map<symbol, number>([
[AclPrivate, 0],
@@ -194,10 +189,15 @@ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number,
if (currentUserGroups.includes(entity) || userChecked === entity) {
if (HierarchyMapping.get(value as symbol)! > HierarchyMapping.get(effectiveAcl)!) {
effectiveAcl = value as symbol;
- if (effectiveAcl === AclAdmin) break;
+ if (effectiveAcl === AclAdmin) return effectiveAcl;
}
}
}
+
+ // if there's an overriding acl set through the properties panel or sharing menu, that's what's returned if the user isn't an admin of the document
+ const override = target[AclSym]["acl-Override"];
+ if (override !== AclUnset && override !== undefined) effectiveAcl = target[AclSym]["acl-Override"];
+
// if we're in playground mode, return AclEdit (or AclAdmin if that's the user's effectiveAcl)
return DocServer?.Control?.isReadOnly?.() && HierarchyMapping.get(effectiveAcl)! < 3 ? AclEdit : effectiveAcl;
}
@@ -280,7 +280,7 @@ export function setter(target: any, in_prop: string | symbol | number, value: an
if (effectiveAcl !== AclEdit && effectiveAcl !== AclAdmin) return true;
// if you're trying to change an acl but don't have Admin access / you're trying to change it to something that isn't an acceptable acl, you can't
- if (typeof prop === "string" && prop.startsWith("acl") && (effectiveAcl !== AclAdmin || ![...Object.values(SharingPermissions), undefined, "unset"].includes(value))) return true;
+ if (typeof prop === "string" && prop.startsWith("acl") && (effectiveAcl !== AclAdmin || ![...Object.values(SharingPermissions), undefined, "None"].includes(value))) return true;
// if (typeof prop === "string" && prop.startsWith("acl") && !["Can Edit", "Can Add", "Can View", "Not Shared", undefined].includes(value)) return true;
if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && (prop.startsWith("_") || layoutProps.includes(prop))) {