From a523190943c71f4728dafd2716c262e17464c012 Mon Sep 17 00:00:00 2001
From: Nimra Ahmed <50912134+nimraahmed@users.noreply.github.com>
Date: Mon, 30 Oct 2023 22:01:58 +0500
Subject: [PATCH] User guide & vale setup (#2260)
* refactored Storybook UI
* refactored Storybook UI
* removed extra cards from the doc, added card for ui components
* added hover behavior to doc page & made it look selected
* separate storybook docs and tests
* separating storybook tests and docs
* fixed spelling errors in docs
* Final round of edits for frontend, added backend folder architecture
* Created CODE_OF_CONDUCT.md
* Add code of conduct to contributing.md
* doc changes
* fixed broken links
* doc addition and changes
* introduce user guide & graphql api
* set up vale, added to docs
* vale config file
* revised backend best practices
* connecting zapier and twenty
* added warning for zapier
---
.vale.ini | 12 +
.../server/others/best-practices.mdx | 26 +
docs/docs/user-guide/connect-zapier.mdx | 27 +
docs/docs/user-guide/custom objects.mdx | 38 +-
docs/docs/user-guide/generating-api-keys.mdx | 26 +
docs/docs/user-guide/zapier integration.mdx | 9 -
docs/docusaurus.config.js | 2 +-
docs/src/css/custom.css | 18 +-
docs/static/img/user-guide/connect-zapier.png | Bin 0 -> 387159 bytes
.../img/user-guide/create-custom-object.gif | Bin 0 -> 12607501 bytes
.../img/user-guide/manage-custom-object.png | Bin 0 -> 352152 bytes
.../img/user-guide/view-all-objects.png | Bin 0 -> 365571 bytes
docs/vale/styles/docs/Acronyms.yml | 79 ++
docs/vale/styles/docs/ComplexWords.yml | 119 +++
docs/vale/styles/docs/Contractions.yml | 49 ++
docs/vale/styles/docs/FirstPerson.yml | 15 +
docs/vale/styles/docs/Foreign.yml | 10 +
docs/vale/styles/docs/Gender.yml | 7 +
docs/vale/styles/docs/HeadingColons.yml | 7 +
docs/vale/styles/docs/HeadingPunctuation.yml | 13 +
docs/vale/styles/docs/Npm2Yarn.yml | 7 +
docs/vale/styles/docs/NpmCommands.yml | 10 +
docs/vale/styles/docs/NpmGlobal.yml | 7 +
docs/vale/styles/docs/Numbers.yml | 13 +
docs/vale/styles/docs/Ordinal.yml | 12 +
docs/vale/styles/docs/Our.yml | 6 +
docs/vale/styles/docs/OxfordComma.yml | 8 +
docs/vale/styles/docs/Passive.yml | 183 +++++
docs/vale/styles/docs/Percentages.yml | 6 +
docs/vale/styles/docs/SentenceLength.yml | 6 +
docs/vale/styles/docs/Spacing.yml | 7 +
docs/vale/styles/docs/Terms.yml | 8 +
docs/vale/styles/docs/TypeScript.yml | 7 +
docs/vale/styles/docs/We.yml | 9 +
docs/vale/styles/docs/Wordiness.yml | 121 +++
docs/vale/styles/docs/WritingLevel.yml | 9 +
docs/vale/styles/write-good/Cliches.yml | 702 ++++++++++++++++++
docs/vale/styles/write-good/E-Prime.yml | 32 +
docs/vale/styles/write-good/Illusions.yml | 11 +
docs/vale/styles/write-good/Passive.yml | 183 +++++
docs/vale/styles/write-good/README.md | 27 +
docs/vale/styles/write-good/So.yml | 5 +
docs/vale/styles/write-good/ThereIs.yml | 6 +
docs/vale/styles/write-good/TooWordy.yml | 221 ++++++
docs/vale/styles/write-good/Weasel.yml | 207 ++++++
docs/vale/styles/write-good/meta.json | 4 +
46 files changed, 2254 insertions(+), 20 deletions(-)
create mode 100644 .vale.ini
create mode 100644 docs/docs/contributor/server/others/best-practices.mdx
create mode 100644 docs/docs/user-guide/connect-zapier.mdx
create mode 100644 docs/docs/user-guide/generating-api-keys.mdx
delete mode 100644 docs/docs/user-guide/zapier integration.mdx
create mode 100644 docs/static/img/user-guide/connect-zapier.png
create mode 100644 docs/static/img/user-guide/create-custom-object.gif
create mode 100644 docs/static/img/user-guide/manage-custom-object.png
create mode 100644 docs/static/img/user-guide/view-all-objects.png
create mode 100644 docs/vale/styles/docs/Acronyms.yml
create mode 100644 docs/vale/styles/docs/ComplexWords.yml
create mode 100644 docs/vale/styles/docs/Contractions.yml
create mode 100644 docs/vale/styles/docs/FirstPerson.yml
create mode 100644 docs/vale/styles/docs/Foreign.yml
create mode 100644 docs/vale/styles/docs/Gender.yml
create mode 100644 docs/vale/styles/docs/HeadingColons.yml
create mode 100644 docs/vale/styles/docs/HeadingPunctuation.yml
create mode 100644 docs/vale/styles/docs/Npm2Yarn.yml
create mode 100644 docs/vale/styles/docs/NpmCommands.yml
create mode 100644 docs/vale/styles/docs/NpmGlobal.yml
create mode 100644 docs/vale/styles/docs/Numbers.yml
create mode 100644 docs/vale/styles/docs/Ordinal.yml
create mode 100644 docs/vale/styles/docs/Our.yml
create mode 100644 docs/vale/styles/docs/OxfordComma.yml
create mode 100644 docs/vale/styles/docs/Passive.yml
create mode 100644 docs/vale/styles/docs/Percentages.yml
create mode 100644 docs/vale/styles/docs/SentenceLength.yml
create mode 100644 docs/vale/styles/docs/Spacing.yml
create mode 100644 docs/vale/styles/docs/Terms.yml
create mode 100644 docs/vale/styles/docs/TypeScript.yml
create mode 100644 docs/vale/styles/docs/We.yml
create mode 100644 docs/vale/styles/docs/Wordiness.yml
create mode 100644 docs/vale/styles/docs/WritingLevel.yml
create mode 100644 docs/vale/styles/write-good/Cliches.yml
create mode 100644 docs/vale/styles/write-good/E-Prime.yml
create mode 100644 docs/vale/styles/write-good/Illusions.yml
create mode 100644 docs/vale/styles/write-good/Passive.yml
create mode 100644 docs/vale/styles/write-good/README.md
create mode 100644 docs/vale/styles/write-good/So.yml
create mode 100644 docs/vale/styles/write-good/ThereIs.yml
create mode 100644 docs/vale/styles/write-good/TooWordy.yml
create mode 100644 docs/vale/styles/write-good/Weasel.yml
create mode 100644 docs/vale/styles/write-good/meta.json
diff --git a/.vale.ini b/.vale.ini
new file mode 100644
index 000000000..98780c02f
--- /dev/null
+++ b/.vale.ini
@@ -0,0 +1,12 @@
+StylesPath = docs/vale/styles
+
+MinAlertLevel = suggestion
+
+Packages = write-good
+
+[*.{md,mdx}]
+BasedOnStyles = Vale, write-good, docs
+
+
+[formats]
+mdx = md
diff --git a/docs/docs/contributor/server/others/best-practices.mdx b/docs/docs/contributor/server/others/best-practices.mdx
new file mode 100644
index 000000000..885aa2afd
--- /dev/null
+++ b/docs/docs/contributor/server/others/best-practices.mdx
@@ -0,0 +1,26 @@
+---
+title: Best Practices
+sidebar_position: 3
+sidebar_custom_props:
+ icon: TbChecklist
+---
+
+This document outlines the best practices you should follow when working on the backend.
+
+## Follow a modular approach
+
+We follow a modular approach for our backend, which is a fundamental principle when working with NestJS. Make sure you break down your code into reusable modules to maintain a clean and organized codebase.
+Each module should encapsulate a particular feature or functionality and have a well-defined scope. This modular approach enables clear separation of concerns and removes unnecessary complexities.
+
+
+## Expose services to be used in modules
+
+We encourage creating services that have a clear and single responsibility, which enhances code readability and maintainability. Services should be named descriptively and consistently.
+
+We also encourage exposing services to be used in other modules. Exposing services to other modules is made possible through NestJS's powerful dependency injection system, and promotes loose coupling between components.
+
+## Avoid using `any` type
+
+When you declare a variable as `any`, TypeScript's type checker doesn't perform any type checking, making it possible to assign any type of values to the variable. TypeScript is designed to use type inference to determine the type of variable based on the value. By declaring it as `any`, TypeScript can no longer infer the type. This makes it hard to catch type-related errors during development, leading to runtime errors and makes the code less maintainable, less reliable, and harder to understand for others.
+
+This is why everything should be typed. So if you create a new object with a first name and last name, you should create an interface or type that contains a first name and last name that defines the shape of the object you are manipulating.
\ No newline at end of file
diff --git a/docs/docs/user-guide/connect-zapier.mdx b/docs/docs/user-guide/connect-zapier.mdx
new file mode 100644
index 000000000..06db6b1b3
--- /dev/null
+++ b/docs/docs/user-guide/connect-zapier.mdx
@@ -0,0 +1,27 @@
+---
+title: Connect Twenty and Zapier
+sidebar_position: 3
+sidebar_custom_props:
+ icon: TbBrandZapier
+---
+
+:::caution
+
+Twenty integration is currently being registered in the public Zapier repository, you may not find it until the publishing process is complete.
+
+:::
+
+Sync Twenty with 3000+ apps using [Zapier](https://zapier.com/), and automate your work. Here's how you can connect Twenty to Zapier:
+
+1. Go to Zapier and log in.
+2. Click on `+ Create Zap` in the left sidebar.
+3. Choose the application you want to set as the trigger. A trigger refers to an event that starts the automation.
+4. Select Twenty as the action. An action is the event that is performed once the automation is triggered. [Learn more about triggers and actions in Zapier.](https://zapier.com/how-it-works)
+5. Once you choose the Twenty account that you want to use for your automation, you'll be prompted to authorize it by adding an API key. You can learn [how to generate your API key here.](generating-api-keys.mdx)
+6. Enter your API key and click on 'Yes, Continue to Twenty.'
+
+
+

+
+
+You can now continue creating your automation!
\ No newline at end of file
diff --git a/docs/docs/user-guide/custom objects.mdx b/docs/docs/user-guide/custom objects.mdx
index f85204b90..660d0d9cf 100644
--- a/docs/docs/user-guide/custom objects.mdx
+++ b/docs/docs/user-guide/custom objects.mdx
@@ -1,9 +1,41 @@
---
-title: Custom Objects
+title: Creating Custom Objects
sidebar_position: 1
-sidebar_class_name: coming-soon
sidebar_custom_props:
icon: TbAugmentedReality
---
-Coming soon!
\ No newline at end of file
+Objects are structures that allow you to store data (records, attributes, and values) specific to an organization. Twenty provides both standard and custom objects.
+
+Standard objects are built-in objects with a set of attributes available for all users. All workspaces come with three standard objects by default: People, Companies, and Opportunities. Standard objects have standard fields that are also available for all Twenty users, like Account Owner and URL.
+
+Custom objects are objects that you can create to store information that is unique to your organization. They are not built-in; members of your workspace can create and customize custom objects to hold information that standard objects aren't suitable for. For example, if you're Airbnb, you may want to create a custom object for Listings or Reservations.
+
+## Creating a new custom object
+
+To create a new custom object:
+
+1. Go to Settings in the sidebar on the left.
+2. Under Workspace, go to Data model. Here you'll be able to see an overview of all your existing Standard and Custom objects (both active and disabled).
+
+
+
+

+
+
+
+3. Click on `+ New object` at the top, then choose Custom as the object type. Enter the name (both singular and plural) and description for your custom object and hit Save (at the top right). Using Listing as an example of custom object, the singular would be "listing" and the plural would be "listings" along with a description like "Listings that hosts created to showcase their property."
+
+
+
+
+

+
+
+
+
+4. Once you create your custom object, you'll be able to manage it. You can edit the name and description, view the different fields, and add more fields.
+
+
+

+
diff --git a/docs/docs/user-guide/generating-api-keys.mdx b/docs/docs/user-guide/generating-api-keys.mdx
new file mode 100644
index 000000000..0d021a0dc
--- /dev/null
+++ b/docs/docs/user-guide/generating-api-keys.mdx
@@ -0,0 +1,26 @@
+---
+title: Generating an API Key
+sidebar_position: 2
+sidebar_custom_props:
+ icon: TbApi
+---
+
+To generate an API key:
+
+1. Go to Settings in the sidebar on the left.
+2. Under Workspace, go to Developers. Here, you'll see a list of active keys that you or your team have created.
+3. To generate a new key, click on `+ Create key` on the top right.
+4. Give your API key a name, an expiration date, and a logo.
+5. Hit save to see your API key.
+6. Since the key is only visible once, make sure you store it somewhere safe.
+
+:::caution Note
+
+You API key contains sensitive information, and shouldn't be shared with services you don't fully trust. If leaked, it can be used maliciously. If you think your API key has been compromised, make sure you disable it and generate a new one.
+
+:::
+
+
+## Regenerating API key
+
+To regenerate an API key, simply click on the key you want to regenerate. You'll then be able to see a button to regenerate the API key.
\ No newline at end of file
diff --git a/docs/docs/user-guide/zapier integration.mdx b/docs/docs/user-guide/zapier integration.mdx
deleted file mode 100644
index 74c3b74fd..000000000
--- a/docs/docs/user-guide/zapier integration.mdx
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: Zapier tutorial
-sidebar_position: 2
-sidebar_class_name: coming-soon
-sidebar_custom_props:
- icon: TbBrandZapier
----
-
-Coming soon!
\ No newline at end of file
diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js
index e71d68b94..8013681ce 100644
--- a/docs/docusaurus.config.js
+++ b/docs/docusaurus.config.js
@@ -42,7 +42,6 @@ const config = {
sidebarCollapsible: false,
routeBasePath: "/",
editUrl: "https://github.com/twentyhq/twenty/edit/main/docs/",
-
},
blog: false,
theme: {
@@ -59,6 +58,7 @@ const config = {
image: "img/social-card.png",
colorMode: {
defaultMode: "light",
+ respectPrefersColorScheme: false,
},
navbar: {
/*title: 'Twenty',*/
diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css
index 600c5bfa7..fa8c06a55 100644
--- a/docs/src/css/custom.css
+++ b/docs/src/css/custom.css
@@ -163,22 +163,26 @@ li.coming-soon a::after {
color:inherit
}
+.menu__list-item--level1 > .menu__link--active {
+ color: inherit;
+}
+
+
.menu__list-item--level1 > .menu__link--active > .icon-and-text {
color: black;
}
-/* Change text color to white for dark mode */
-@media (prefers-color-scheme: dark) {
- .menu__list-item--level1 > .menu__link--active > .icon-and-text {
- color: white;
- }
+
+[data-theme='dark'] .menu__list-item--level1 > .menu__link--active > .icon-and-text {
+ color: white;
}
-/* Reset to the browser's default text color for other cases (light mode) */
-.menu__list-item--level1 > .menu__link--active > .icon-and-text {
+
+[data-theme='light'] .menu__list-item--level1 > .menu__link--active > .icon-and-text {
color: initial;
}
+
.menu__list-item--level1 > .menu__link--active,
diff --git a/docs/static/img/user-guide/connect-zapier.png b/docs/static/img/user-guide/connect-zapier.png
new file mode 100644
index 0000000000000000000000000000000000000000..ddbb27aca98bf7ecd93e8adb22b28323a44cb6f6
GIT binary patch
literal 387159
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