Replace legacy isDeveloper/isAdmin/hasRoles checks with hasPermission/requirePermission across all collections. Add roleDocs relationship to Users, enlistmentDate to Profiles, and field-level intel_excerpt permission gate on Profiles. Auto-generated payload-types updated to reflect the new Roles collection and roleDocs field.
202 lines
5.8 KiB
TypeScript
202 lines
5.8 KiB
TypeScript
import { CollectionConfig } from "payload";
|
|
import { requirePermission } from "@/utils/access-control/hasPermission";
|
|
|
|
export const Technologies: CollectionConfig = {
|
|
slug: "technologies",
|
|
admin: {
|
|
group: "Intelligence",
|
|
useAsTitle: "name",
|
|
},
|
|
access: {
|
|
create: requirePermission("technologies:create"),
|
|
update: requirePermission("technologies:update"),
|
|
delete: requirePermission("technologies:delete"),
|
|
read: requirePermission("technologies:read"),
|
|
},
|
|
fields: [
|
|
{
|
|
name: "name",
|
|
type: "text",
|
|
required: true,
|
|
},
|
|
{
|
|
name: "approvalStatus",
|
|
type: "select",
|
|
label: "Approval Status",
|
|
options: [
|
|
{ label: "In Progress", value: "in_progress" },
|
|
{ label: "Ready for Review", value: "ready_for_review" },
|
|
{ label: "Approved", value: "approved" },
|
|
{ label: "Rejected", value: "rejected" },
|
|
{ label: "Revision Requested", value: "revision_requested" },
|
|
],
|
|
defaultValue: "in_progress",
|
|
filterOptions: ({ options, req }) => {
|
|
const roles = (req.user?.roles as string[] | undefined) ?? [];
|
|
const canReadAll = roles.includes("admin") || roles.includes("developer");
|
|
if (canReadAll) return options;
|
|
return options.filter((option) =>
|
|
typeof option === "string"
|
|
? options
|
|
: ["in_progress", "ready_for_review"].includes(option.value),
|
|
);
|
|
},
|
|
required: true,
|
|
admin: {
|
|
description:
|
|
"Mark whether this technology is ready for developer approval and implementation into the live environment.",
|
|
},
|
|
},
|
|
{
|
|
name: "type",
|
|
type: "select",
|
|
options: [
|
|
{
|
|
label: "Asset",
|
|
value: "asset",
|
|
},
|
|
{
|
|
label: "Upgrade",
|
|
value: "upgrade",
|
|
},
|
|
],
|
|
admin: {
|
|
description:
|
|
'An "Asset" technology will unlock a new item, vehicle, gear piece, structure, etc. An "Upgrade" technology will unlock an improvement to an Asset, like faster build speed, more storage capacity, etc.',
|
|
},
|
|
required: true,
|
|
defaultValue: "upgrade",
|
|
},
|
|
{
|
|
name: "summary",
|
|
type: "textarea",
|
|
required: true,
|
|
},
|
|
{
|
|
name: "description",
|
|
type: "richText",
|
|
},
|
|
{
|
|
name: "requirements",
|
|
type: "group",
|
|
fields: [
|
|
{
|
|
name: "prerequisiteTechnologies",
|
|
type: "array",
|
|
fields: [
|
|
{
|
|
type: "row",
|
|
fields: [
|
|
{
|
|
name: "requiresAnd",
|
|
type: "group",
|
|
label: "Requires (AND)",
|
|
admin: {
|
|
description:
|
|
"ALL of these technologies MUST be unlocked before this one can be.",
|
|
},
|
|
fields: [
|
|
{
|
|
name: "technology",
|
|
type: "relationship",
|
|
relationTo: "technologies",
|
|
hasMany: true,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: "requiresOr",
|
|
type: "group",
|
|
label: "Requires (OR)",
|
|
admin: {
|
|
description:
|
|
"One or more of these technologies MUST be unlocked before this one can be.",
|
|
},
|
|
fields: [
|
|
{
|
|
name: "technology",
|
|
type: "relationship",
|
|
relationTo: "technologies",
|
|
hasMany: true,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: "researchCosts",
|
|
type: "group",
|
|
fields: [
|
|
{
|
|
name: "resources",
|
|
type: "array",
|
|
fields: [
|
|
{
|
|
name: "resource",
|
|
type: "relationship",
|
|
relationTo: "resources",
|
|
required: true,
|
|
},
|
|
{
|
|
name: "amount",
|
|
type: "number",
|
|
defaultValue: 1,
|
|
required: true,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: "row",
|
|
fields: [
|
|
{
|
|
name: "minimumResearchDuration",
|
|
type: "number",
|
|
admin: {
|
|
components: {
|
|
Description: {
|
|
path: "@/components/static/TickDurationDescription",
|
|
clientProps: {
|
|
task: "research this technology",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
min: 1,
|
|
max: 10000,
|
|
required: true,
|
|
defaultValue: 0,
|
|
},
|
|
{
|
|
name: "maximumResearchDuration",
|
|
type: "number",
|
|
admin: {
|
|
components: {
|
|
Description: {
|
|
path: "@/components/static/TickDurationDescription",
|
|
clientProps: {
|
|
task: "research this technology",
|
|
field: "maximumResearchDuration",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
min: 1,
|
|
max: 10000,
|
|
/*validate: (value: number, { data, siblingData }: { data: any; siblingData: any }) => {
|
|
const minDuration = siblingData?.minimumResearchDuration;
|
|
if (value !== undefined && minDuration !== undefined && value < minDuration) {
|
|
return `Maximum research duration must be at least ${minDuration} (the minimum research duration)`;
|
|
}
|
|
return true;
|
|
},*/
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|