diff --git a/apps/strapi/config/plugins.ts b/apps/strapi/config/plugins.ts index f55325d..e110c27 100644 --- a/apps/strapi/config/plugins.ts +++ b/apps/strapi/config/plugins.ts @@ -108,6 +108,27 @@ export default ({ env }) => { ? "blog-posts-production" : "blog-posts-testing", }, + feature: { + indexName: env.bool("MEILISEARCH_PRODUCTION", false) + ? "features-production" + : "features-testing", + entriesQuery: { + populate: { + icon: true, + feature_tag: { fields: ["title"] }, + }, + }, + transformEntry({ entry }) { + return { + ...entry, + feature_tag: entry.feature_tag?.title ?? null, + } + }, + settings: { + filterableAttributes: ["feature_tag"], + searchableAttributes: ["title", "description"], + }, + }, }, }, diff --git a/apps/strapi/database/migrations/features.json b/apps/strapi/database/migrations/features.json new file mode 100644 index 0000000..38bac1b --- /dev/null +++ b/apps/strapi/database/migrations/features.json @@ -0,0 +1,238 @@ +{ + "cards": [ + { + "label": "Content Management", + "title": "Internationalization (i18n)", + "description": "Manage and publish content in multiple locales, allowing for localized content strategies and broader audience engagement.", + "url": "https://strapi.io/features/internationalization" + }, + { + "label": "Content Management", + "title": "Blocks Editor", + "description": "Drag and drop rich text in a user-friendly WYSIWYG environment, making content creation seamless and straightforward.", + "url": "https://docs.strapi.io/cms/features/content-type-builder" + }, + { + "label": "Content Management", + "title": "Dynamic Zones", + "description": "Editors adjust layouts with dynamic components for flexible page design.", + "url": "https://strapi.io/features/dynamic-zone" + }, + { + "label": "Content Management", + "title": "Content History", + "description": "No more headaches over lost edits or accidental changes. Keep your workflow smooth and stress-free with Content History.", + "url": "https://strapi.io/features/content-history" + }, + { + "label": "Content Management", + "title": "Live Preview", + "description": "Live preview changes before publishing to enable collaboration and confident content validation.", + "url": "https://strapi.io/features/live-preview" + }, + { + "label": "Customization", + "title": "Conditional Fields", + "description": "Give editors a smarter, more intuitive content-editing experience by showing only the fields that matter.", + "url": "https://strapi.io/features/conditional-fields" + }, + { + "label": "Create APIs", + "title": "Content GraphQL API", + "description": "The GraphQL API allows performing queries and mutations to interact with the content-types through Strapi's GraphQL plugin.", + "url": "https://strapi.io/features/customizable-api" + }, + { + "label": "Security", + "title": "API Tokens", + "description": "Manage end-user access to your API securely with customizable tokens, ensuring that data exposure is controlled and intentional.", + "url": "https://docs.strapi.io/user-docs/settings/API-tokens" + }, + { + "label": "Security", + "title": "TypeScript Support", + "description": "Improve coding practices and reduce errors with full TypeScript support, ensuring a more secure and maintainable codebase.", + "url": "https://docs.strapi.io/dev-docs/typescript/development" + }, + { + "label": "Security", + "title": "Audit Logs", + "description": "Keep a detailed record of every action taken within your CMS, allowing for better security monitoring and compliance.", + "url": "https://strapi.io/features/audit-logs" + }, + { + "label": "Security", + "title": "RBAC", + "description": "Control access and permissions within your CMS with advanced role-based access control, enhancing security and compliance.", + "url": "https://strapi.io/features/custom-roles-and-permissions" + }, + { + "label": "Security", + "title": "Single Sign-On (SSO)", + "description": "Simplify user authentication with Single Sign-On from major third-party providers, streamlining access while maintaining security.", + "url": "https://strapi.io/features/single-sign-on-sso" + }, + { + "label": "Hosting", + "title": "Upload Providers", + "description": "Use your preferred CDN for faster content delivery, optimizing user experience across different geographies.", + "url": "https://docs.strapi.io/cloud/advanced/upload" + }, + { + "label": "Hosting", + "title": "PostgreSQL Database", + "description": "Integrate smoothly with your favorite SQL databases, customizing data storage and retrieval to fit your needs.", + "url": "https://docs.strapi.io/cloud/advanced/database" + }, + { + "label": "Hosting", + "title": "Cloud CLI", + "description": "Deploy your Strapi projects directly from the terminal, making the process straightforward and efficient.", + "url": "https://docs.strapi.io/cloud/cli/cloud-cli" + }, + { + "label": "Hosting", + "title": "GitLab Integration", + "description": "Deploy from your GitLab repository, maintaining workflow efficiency and consistency.", + "url": "https://docs.strapi.io/cloud/account/account-settings" + }, + { + "label": "Create APIs", + "title": "Content REST API", + "description": "Integrate dynamic content delivery with a standard RESTful approach, making it easy to fetch and display content as needed.", + "url": "https://strapi.io/features/customizable-api" + }, + { + "label": "Hosting", + "title": "GitHub Integration", + "description": "Deploy code directly from your GitHub repository, facilitating continuous integration and faster updates.", + "url": "https://docs.strapi.io/cloud/account/account-settings" + }, + { + "label": "Hosting", + "title": "Built-in Email Provider", + "description": "Send emails directly through a built-in provider, streamlining communication and marketing efforts.", + "url": "https://docs.strapi.io/cloud/advanced/email" + }, + { + "label": "Hosting", + "title": "Built-in CDN", + "description": "Serve content efficiently with a built-in CDN, reducing load times and improving accessibility.", + "url": "https://docs.strapi.io/cloud/getting-started/caching" + }, + { + "label": "Hosting", + "title": "Backups", + "description": "Secure your CMS data with automatic backups, protecting against data loss and ensuring business continuity.", + "url": "https://docs.strapi.io/cloud/projects/settings" + }, + { + "label": "Hosting", + "title": "Strapi Cloud", + "description": "Host your CMS with our dedicated cloud service, designed for performance and ease of use.", + "url": "https://strapi.io/cloud" + }, + { + "label": "Customization", + "title": "Widget API", + "description": "Build your own widgets to surface the metrics, links, and insights you care about most. Add charts, content summaries, custom workflows, and more, right on your homepage.", + "url": "https://docs.strapi.io/cms/admin-panel-customization/homepage" + }, + { + "label": "Customization", + "title": "Plugin SDK", + "description": "The Plugin SDK is set of commands provided to create a plugin from scratch, link it to an existing project, and publish it.", + "url": "https://docs.strapi.io/dev-docs/plugins/development/plugin-sdk" + }, + { + "label": "Customization", + "title": "Plugin API", + "description": "Extend your CMS with custom plugins, creating tailored solutions for unique project needs.", + "url": "https://docs.strapi.io/dev-docs/plugins" + }, + { + "label": "Customization", + "title": "Design System", + "description": "The Strapi Design System is a collection of standards, foundations, components & hooks to make contributions and plugins more efficient and cohesive.", + "url": "https://design-system.strapi.io/?path=%2Fdocs%2Fgetting-started-welcome--docs" + }, + { + "label": "Customization", + "title": "Document Service API", + "description": "The Document Service API is built on top of the Query Engine API and used to perform CRUD (create, retrieve, update, and delete) operations on documents.", + "url": "https://docs.strapi.io/dev-docs/api/document-service" + }, + { + "label": "Create APIs", + "title": "Relations", + "description": "Design a custom content architecture that links your data in meaningful ways, organizing data in a way that makes sense for your application and your team.", + "url": "https://strapi.io/features/relations" + }, + { + "label": "Customization", + "title": "Custom Layout", + "description": "Personalize the content editing experience with custom layouts, enhancing usability and editor satisfaction.", + "url": "https://docs.strapi.io/dev-docs/plugins/admin-panel-api" + }, + { + "label": "Customization", + "title": "Webhooks", + "description": "Trigger actions automatically in your CMS or other integrated systems, improving operational efficiency.", + "url": "https://docs.strapi.io/dev-docs/backend-customization/webhooks" + }, + { + "label": "Customization", + "title": "Custom Fields", + "description": "Add any type of fields to your project, customizing data structures to suit your specific requirements.", + "url": "https://docs.strapi.io/dev-docs/custom-fields" + }, + { + "label": "Customization", + "title": "Marketplace", + "description": "Benefit from additional features developed by the community, enhancing your CMS with new functionalities.", + "url": "https://market.strapi.io/" + }, + { + "label": "Collaboration", + "title": "RBAC for admins", + "description": "Control access and permissions within your CMS with advanced role-based access control, enhancing security and compliance.", + "url": "https://docs.strapi.io/dev-docs/configurations/guides/rbac" + }, + { + "label": "Collaboration", + "title": "RBAC for end-users", + "description": "Manage the permissions of end-users who consume the content that is created and managed with a Strapi application and displayed on front-end applications.", + "url": "https://docs.strapi.io/dev-docs/configurations/guides/rbac" + }, + { + "label": "Collaboration", + "title": "Review Workflows", + "description": "Set up predefined approval processes that ensure every piece of content meets your standards before it's published.", + "url": "https://strapi.io/features/review-workflow" + }, + { + "label": "Collaboration", + "title": "Releases", + "description": "Group and manage the publication of your content, allowing for better control over when and how content goes live.", + "url": "https://strapi.io/features/releases" + }, + { + "label": "Content Management", + "title": "Cron Jobs", + "description": "Automate publishing and other repetitive tasks, optimizing workflow efficiency and ensuring timely content updates.", + "url": "https://docs.strapi.io/dev-docs/configurations/cron" + }, + { + "label": "Content Management", + "title": "Media Library", + "description": "Efficiently organize, store, and access media files, streamlining content creation and management processes.", + "url": "https://strapi.io/features/media-library" + }, + { + "label": "Create APIs", + "title": "Content-Type Builder", + "description": "Create and manage content models through a user-friendly interface, simplifying the development process.", + "url": "https://strapi.io/features/content-types-builder" + } + ] +} diff --git a/apps/strapi/src/api/feature-tag/content-types/feature-tag/schema.json b/apps/strapi/src/api/feature-tag/content-types/feature-tag/schema.json new file mode 100644 index 0000000..4941efe --- /dev/null +++ b/apps/strapi/src/api/feature-tag/content-types/feature-tag/schema.json @@ -0,0 +1,24 @@ +{ + "kind": "collectionType", + "collectionName": "feature_tags", + "info": { + "singularName": "feature-tag", + "pluralName": "feature-tags", + "displayName": "Feature tag" + }, + "options": { + "draftAndPublish": true + }, + "pluginOptions": {}, + "attributes": { + "title": { + "type": "string" + }, + "features": { + "type": "relation", + "relation": "oneToMany", + "target": "api::feature.feature", + "mappedBy": "feature_tag" + } + } +} diff --git a/apps/strapi/src/api/feature-tag/controllers/feature-tag.ts b/apps/strapi/src/api/feature-tag/controllers/feature-tag.ts new file mode 100644 index 0000000..0ade4b5 --- /dev/null +++ b/apps/strapi/src/api/feature-tag/controllers/feature-tag.ts @@ -0,0 +1,7 @@ +/** + * feature-tag controller + */ + +import { factories } from "@strapi/strapi" + +export default factories.createCoreController("api::feature-tag.feature-tag") diff --git a/apps/strapi/src/api/feature-tag/routes/feature-tag.ts b/apps/strapi/src/api/feature-tag/routes/feature-tag.ts new file mode 100644 index 0000000..1dc0522 --- /dev/null +++ b/apps/strapi/src/api/feature-tag/routes/feature-tag.ts @@ -0,0 +1,7 @@ +/** + * feature-tag router + */ + +import { factories } from "@strapi/strapi" + +export default factories.createCoreRouter("api::feature-tag.feature-tag") diff --git a/apps/strapi/src/api/feature-tag/services/feature-tag.ts b/apps/strapi/src/api/feature-tag/services/feature-tag.ts new file mode 100644 index 0000000..c0f58a6 --- /dev/null +++ b/apps/strapi/src/api/feature-tag/services/feature-tag.ts @@ -0,0 +1,7 @@ +/** + * feature-tag service + */ + +import { factories } from "@strapi/strapi" + +export default factories.createCoreService("api::feature-tag.feature-tag") diff --git a/apps/strapi/src/api/feature/content-types/feature/schema.json b/apps/strapi/src/api/feature/content-types/feature/schema.json new file mode 100644 index 0000000..0b38748 --- /dev/null +++ b/apps/strapi/src/api/feature/content-types/feature/schema.json @@ -0,0 +1,37 @@ +{ + "kind": "collectionType", + "collectionName": "features", + "info": { + "singularName": "feature", + "pluralName": "features", + "displayName": "Feature" + }, + "options": { + "draftAndPublish": true + }, + "pluginOptions": {}, + "attributes": { + "title": { + "type": "string" + }, + "description": { + "type": "text" + }, + "icon": { + "type": "media", + "multiple": false, + "allowedTypes": [ + "images" + ] + }, + "feature_tag": { + "type": "relation", + "relation": "manyToOne", + "target": "api::feature-tag.feature-tag", + "inversedBy": "features" + }, + "url": { + "type": "string" + } + } +} diff --git a/apps/strapi/src/api/feature/controllers/feature.ts b/apps/strapi/src/api/feature/controllers/feature.ts new file mode 100644 index 0000000..2c95e09 --- /dev/null +++ b/apps/strapi/src/api/feature/controllers/feature.ts @@ -0,0 +1,7 @@ +/** + * feature controller + */ + +import { factories } from "@strapi/strapi" + +export default factories.createCoreController("api::feature.feature") diff --git a/apps/strapi/src/api/feature/routes/feature.ts b/apps/strapi/src/api/feature/routes/feature.ts new file mode 100644 index 0000000..55af06a --- /dev/null +++ b/apps/strapi/src/api/feature/routes/feature.ts @@ -0,0 +1,7 @@ +/** + * feature router + */ + +import { factories } from "@strapi/strapi" + +export default factories.createCoreRouter("api::feature.feature") diff --git a/apps/strapi/src/api/feature/services/feature.ts b/apps/strapi/src/api/feature/services/feature.ts new file mode 100644 index 0000000..18df8b5 --- /dev/null +++ b/apps/strapi/src/api/feature/services/feature.ts @@ -0,0 +1,7 @@ +/** + * feature service + */ + +import { factories } from "@strapi/strapi" + +export default factories.createCoreService("api::feature.feature") diff --git a/apps/strapi/types/generated/contentTypes.d.ts b/apps/strapi/types/generated/contentTypes.d.ts index d5740d4..7d32888 100644 --- a/apps/strapi/types/generated/contentTypes.d.ts +++ b/apps/strapi/types/generated/contentTypes.d.ts @@ -951,6 +951,70 @@ export interface ApiCountryCountry extends Struct.CollectionTypeSchema { } } +export interface ApiFeatureTagFeatureTag extends Struct.CollectionTypeSchema { + collectionName: "feature_tags" + info: { + displayName: "Feature tag" + pluralName: "feature-tags" + singularName: "feature-tag" + } + options: { + draftAndPublish: true + } + attributes: { + createdAt: Schema.Attribute.DateTime + createdBy: Schema.Attribute.Relation<"oneToOne", "admin::user"> & + Schema.Attribute.Private + features: Schema.Attribute.Relation<"oneToMany", "api::feature.feature"> + locale: Schema.Attribute.String & Schema.Attribute.Private + localizations: Schema.Attribute.Relation< + "oneToMany", + "api::feature-tag.feature-tag" + > & + Schema.Attribute.Private + publishedAt: Schema.Attribute.DateTime + title: Schema.Attribute.String + updatedAt: Schema.Attribute.DateTime + updatedBy: Schema.Attribute.Relation<"oneToOne", "admin::user"> & + Schema.Attribute.Private + } +} + +export interface ApiFeatureFeature extends Struct.CollectionTypeSchema { + collectionName: "features" + info: { + displayName: "Feature" + pluralName: "features" + singularName: "feature" + } + options: { + draftAndPublish: true + } + attributes: { + createdAt: Schema.Attribute.DateTime + createdBy: Schema.Attribute.Relation<"oneToOne", "admin::user"> & + Schema.Attribute.Private + description: Schema.Attribute.Text + feature_tag: Schema.Attribute.Relation< + "manyToOne", + "api::feature-tag.feature-tag" + > + icon: Schema.Attribute.Media<"images"> + locale: Schema.Attribute.String & Schema.Attribute.Private + localizations: Schema.Attribute.Relation< + "oneToMany", + "api::feature.feature" + > & + Schema.Attribute.Private + publishedAt: Schema.Attribute.DateTime + title: Schema.Attribute.String + updatedAt: Schema.Attribute.DateTime + updatedBy: Schema.Attribute.Relation<"oneToOne", "admin::user"> & + Schema.Attribute.Private + url: Schema.Attribute.String + } +} + export interface ApiFooterFooter extends Struct.SingleTypeSchema { collectionName: "footers" info: { @@ -2133,6 +2197,8 @@ declare module "@strapi/strapi" { "api::cms-comparison.cms-comparison": ApiCmsComparisonCmsComparison "api::cms.cms": ApiCmsCms "api::country.country": ApiCountryCountry + "api::feature-tag.feature-tag": ApiFeatureTagFeatureTag + "api::feature.feature": ApiFeatureFeature "api::footer.footer": ApiFooterFooter "api::global.global": ApiGlobalGlobal "api::header.header": ApiHeaderHeader