Skip to content

Commit 249c2ff

Browse files
committed
setup app and add readme
1 parent 002ac33 commit 249c2ff

File tree

408 files changed

+23223
-13
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

408 files changed

+23223
-13
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
.pos
3+
tmp

README.md

+89-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,89 @@
1-
# pos-module-chat
1+
# Chat Module
2+
3+
This module serves as a starting point for adding real time chat to your application. Before using the module for the first time, we recommend reading the official platformOS documentation on [WebSockets](https://documentation.platformos.com/use-cases/using-websockets) and on [Example Application](#example-application).
4+
5+
This module follows the [platformOS DevKit best practices](https://documentation.staging.oregon.platform-os.com/developer-guide/modules/platformos-modules) and includes the [core module](https://github.com/Platform-OS/pos-module-core) as a dependency, enabling you to implement patterns such as [Commands](https://github.com/Platform-OS/pos-module-core?tab=readme-ov-file#commands--business-logic) and [Events](https://github.com/Platform-OS/pos-module-core?tab=readme-ov-file#events). It also includes the [user module](https://github.com/Platform-OS/pos-module-user) and [profile module](https://github.com/Platform-OS/pos-module-profile) as a dependency.
6+
7+
For more information,
8+
- read the documentation about the [built-in User table](https://documentation.platformos.com/developer-guide/users/user),
9+
- learn about [how platformOS manages sessions](https://documentation.platformos.com/developer-guide/users/session),
10+
- and gain a high-level overview of [authentication strategies in platformOS](https://documentation.platformos.com/developer-guide/users/authentication).
11+
12+
## Installation
13+
14+
The platformOS Chat Module is available on the [Partner Portal Modules Marketplace](https://partners.platformos.com/marketplace/pos_modules/152).
15+
16+
### Prerequisites
17+
18+
Before installing the module, ensure that you have [pos-cli](https://github.com/mdyd-dev/pos-cli#overview) installed. This tool is essential for managing and deploying platformOS projects.
19+
20+
The platformOS Chat Module is fully compatible with [platformOS Check](https://github.com/Platform-OS/platformos-lsp#platformos-check----a-linter-for-platformos), a linter and language server that supports any IDE with Language Server Protocol (LSP) integration. For Visual Studio Code users, you can enhance your development experience by installing the [VSCode platformOS Check Extension](https://marketplace.visualstudio.com/items?itemName=platformOS.platformos-check-vscode).
21+
22+
### Installation Steps
23+
24+
1. **Navigate to your project directory** where you want to install the Chat Module.
25+
26+
2. **Run the installation command**:
27+
28+
```bash
29+
pos-cli modules install chat
30+
```
31+
32+
This command installs the Chat Module along with its dependencies (such as [pos-module-core](https://github.com/Platform-OS/pos-module-core)) and updates or creates the `app/pos-modules.json` file in your project directory to track module configurations.
33+
34+
### Setup
35+
36+
1. **Install the module** using the [pos-cli](https://github.com/Platform-OS/pos-cli).
37+
38+
2. If you haven't done it already, follow the instructions to setup [pos-module-user-](https://github.com/Platform-OS/pos-module-user?tab=readme-ov-file#setup). During this process, you will create an overwrite of the permissions file `app/modules/user/public/lib/queries/role_permissions/permissions.liquid`
39+
40+
3. Overwrite default views that you would like to customize by following the guide on [overwriting a module file](https://documentation.platformos.com/developer-guide/modules/modules#overwritting-a-module-file). This allows you to add functionality based on your project requirements. At a minimum, you should overwrite the [permissions file](modules/user/public/lib/queries/role_permissions/permissions.liquid), where you will configure [RBAC authorization](#rbac-authorization) roles and permissions for your application - add `chat.inbox` permission to the role(s) that you would like to have access to the chat available at `/inbox`. In our example, the `inbox.chat` permission was added to `authenticated` role, meaning all signed in users have access to the chat. Snippet to create an overwrite to copy-paste into your terminal:
41+
42+
```
43+
mkdir -p app/modules/user/public/lib/queries/role_permissions
44+
cp modules/user/public/lib/queries/role_permissions/permissions.liquid app/modules/user/public/lib/queries/role_permissions/permissions.liquid
45+
```
46+
47+
### Managing Module Files
48+
49+
The default behavior of modules is that **the files are never deleted**. It is assumed that developers might not have access to all of the files, and thanks to this feature, they can still overwrite some of the module's files without breaking them. Since the User Module is fully public, it is recommended to delete files on deployment. To do this, ensure your `app/config.yml` includes the User Module and its dependencies in the list `modules_that_allow_delete_on_deploy`:
50+
51+
``` yaml
52+
modules_that_allow_delete_on_deploy:
53+
- core
54+
- user
55+
- profile
56+
- chat
57+
```
58+
59+
## Example application
60+
61+
We recommend creating a [new Instance](https://partners.platformos.com/instances/new) and deploying this module as an application to get a better understanding of the basics and the functionality this module provides. When you install the module using `pos-cli modules install chat`, only the contents of the `modules/chat` will be available in your project. The `app` directory serves as an example of how you could incorporate the Chat Module into your application. When analyzing the code in the `app` directory, pay attention to the following files:
62+
63+
* ** `app/config.yml`** and **`app/user.yml`**: These files are defined according to the [Setup](#setup) instructions.
64+
* ** `app/modules/user/public/lib/queries/role_permissions/permissions.liquid`**: Demonstrates how to configure permissions in your application by [overwriting a module file](https://documentation.platformos.com/developer-guide/modules/modules#overwriting-a-module-file).
65+
66+
## Functionality provided by the chat module:
67+
68+
Once the module is installed and you have completed the [setup](#setup), you will immediately gain access to the new endpoints created by this module. For example, you can navigate to `/inbox` for the chat window.
69+
70+
- [x] **[Inbox](#inbox)**:
71+
72+
TODO (Upcoming Features)
73+
74+
75+
### Inbox
76+
77+
Inbox
78+
79+
#### Endpoints for the registration
80+
81+
The table below outlines the [resourceful routes](https://documentation.platformos.com/developer-guide/modules/platformos-modules#resourceful-route-naming-convention) provided for registration functionality:
82+
83+
| HTTP method | slug | page file path | description
84+
|---|---|---|---|---|
85+
| GET | /inbox | `modules/chat/public/views/pages/inbox.liquid` | Renders a chat |
86+
87+
#### CRUD commands
88+
89+
...

app/config.yml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
theme_search_paths:
2+
- ''
3+
- modules/chat
4+
- modules/user
5+
- modules/components
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{% parse_json fields %}
2+
[
3+
{
4+
"name": "first_name",
5+
"required": true,
6+
"type": "text",
7+
"weight": 0,
8+
"label": "First name"
9+
},
10+
{
11+
"name": "last_name",
12+
"required": true,
13+
"type": "text",
14+
"weight": 1,
15+
"label": "Last name"
16+
},
17+
{
18+
"name": "email",
19+
"required": true,
20+
"type": "email",
21+
"weight": 2,
22+
"label": "Email"
23+
},
24+
{
25+
"name": "password",
26+
"required": true,
27+
"type": "password",
28+
"weight": 3,
29+
"label": "Password"
30+
},
31+
{
32+
"name": "timezone",
33+
"type": "hidden",
34+
"weight": 4
35+
}
36+
]
37+
{% endparse_json %}
38+
39+
{%liquid
40+
return fields
41+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{% parse_json data %}
2+
{
3+
{% if context.constants.USER_DEFAULT_ROLE != blank %}
4+
"{{ context.constants.USER_DEFAULT_ROLE }}": [],
5+
{% endif %}
6+
"anonymous": ["sessions.create", "users.register"],
7+
"authenticated": ["sessions.destroy", "chat.inbox"]
8+
}
9+
{% endparse_json %}
10+
11+
{% return data %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
method: post
3+
slug: users
4+
---
5+
{% liquid
6+
function current_user = 'modules/user/queries/user/current'
7+
include 'modules/user/helpers/can_do_or_unauthorized', requester: current_user, do: 'users.register'
8+
9+
assign profile_object = context.params | deep_clone | hash_merge: user_id: '0'
10+
function profile_object = 'modules/profile/commands/profiles/create_validate', object: profile_object
11+
function object = 'modules/user/commands/user/create', email: context.params.email, password: context.params.password
12+
if profile_object.valid and object.valid
13+
assign profile_object = null | hash_merge: context.params | hash_merge: user_id: object.id
14+
function profile = 'modules/profile/commands/profiles/create', object: profile_object
15+
if profile.valid
16+
function _ = 'modules/user/commands/session/create', user_id: object.id, validate_password: false
17+
else
18+
log profile, type: 'ERROR: users/create profile'
19+
endif
20+
21+
assign redirect_path = '/'
22+
redirect_to redirect_path
23+
else
24+
function registration_fields = 'modules/user/queries/registration_fields/load'
25+
assign values = params | hash_merge: password: ''
26+
theme_render_rc 'modules/user/users/new', context: context, registration_fields: registration_fields, errors: object.errors, values: values
27+
endif
28+
%}

app/pos-modules.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"modules": {
3+
"profile": "1.0.11",
4+
"user": "3.0.7",
5+
"components": "1.1.3"
6+
}
7+
}

app/pos-modules.lock.json

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"modules": {
3+
"profile": "1.0.11",
4+
"user": "3.0.7",
5+
"components": "1.1.3",
6+
"core": "1.5.5"
7+
}
8+
}

app/user.yml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
properties:
2+
- name: roles
3+
type: array

app/views/pages/index.liquid

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{% liquid
2+
function current_profile = 'modules/profile/queries/profiles/find', user_id: context.current_user.id, id: null, uuid: null, first_name: null, last_name: null
3+
4+
if current_profile
5+
function profiles = 'modules/profile/queries/profiles/search', limit: 20, not_ids: null, uuid: null, id: null, ids: null, first_name: null, last_name: null, user_id: null, query: null, emails: null, sort: null
6+
endif
7+
8+
render 'home/index', current_profile: current_profile, profiles: profiles
9+
%}

app/views/partials/home/index.liquid

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{% if current_profile.id %}
2+
Logged in as {{ current_profile.first_name }} {{ context.current_user.email }}
3+
<form action="/sessions" method="post">
4+
<input type="hidden" name="authenticity_token" value="{{ context.authenticity_token }}">
5+
<input type="hidden" name="_method" value="delete" />
6+
<button type="submit">
7+
{{ 'modules/user/users.logout' | t }}
8+
</button>
9+
</form>
10+
<a href="/inbox">Inbox</a><br/>
11+
12+
<ul>
13+
{% for profile in profiles.results %}
14+
{% if profile.id == current_profile.id %}{% continue %}{% endif %}
15+
16+
{% assign chat_url = '/inbox/?to_uuid=' | append: profile.uuid %}
17+
<li>{{ profile.name }} - <a href="{{ chat_url }}">Message</a></li>
18+
{% endfor %}
19+
</ul>
20+
{% else %}
21+
<a href="/users/new">Register</a><br/>
22+
<a href="/sessions/new">Log in</a><br/>
23+
<a href="/passwords/reset">Reset password</a>
24+
{% endif %}

modules/chat/public/views/pages/api/messages/show.json.liquid

+7-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,13 @@ method: get
1313
{% endcomment %}
1414

1515
{% liquid
16-
function current_profile = 'modules/community/helpers/current_profile', user_id: context.current_user.id
17-
include 'modules/community/helpers/profile_present_or_redirect', profile: current_profile
16+
function current_user = 'modules/user/queries/user/current'
17+
18+
# platformos-check-disable ConvertIncludeToRenderl, UnreachableCode
19+
include 'modules/user/helpers/can_do_or_unauthorized', requester: current_user, do: 'chat.inbox', return_url: '/'
20+
# platformos-check-enable ConvertIncludeToRender, UnreachableCode
21+
22+
function current_profile = 'modules/profile/queries/profiles/find', user_id: current_user.id, id: null, uuid: null, first_name: null, last_name: null
1823

1924
assign conversation_id = context.params.conversation_id
2025
assign page = context.params.page | plus: 0 | default: 1

modules/chat/public/views/pages/inbox.html.liquid

+7-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ slug: inbox
33
---
44

55
{% liquid
6-
function current_profile = 'modules/community/helpers/current_profile', user_id: context.current_user.id
7-
include 'modules/community/helpers/profile_present_or_redirect', profile: current_profile
6+
function current_user = 'modules/user/queries/user/current'
7+
8+
# platformos-check-disable ConvertIncludeToRenderl, UnreachableCode
9+
include 'modules/user/helpers/can_do_or_unauthorized', requester: current_user, do: 'chat.inbox', return_url: '/'
10+
# platformos-check-enable ConvertIncludeToRender, UnreachableCode
11+
12+
function current_profile = 'modules/profile/queries/profiles/find', user_id: current_user.id, id: null, uuid: null, first_name: null, last_name: null
813

914
function record = 'modules/chat/lib/queries/records/find_by_uuid', uuid: context.params['to_uuid']
1015
assign object = null | hash_merge: to_id: record.id, conversation_id: context.params['conversation_id']

modules/chat/public/views/partials/lib/queries/conversations/find.liquid

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
endif
66

77
graphql r = 'modules/chat/conversations/search', limit: 1, id: id, participant_id: participant_id, include_messages: include_messages
8-
include 'modules/community/helpers/handle_graphql_response', r: r, name: 'modules/chat/conversations/find_by_participant'
98

109
assign conversation = r.conversations.results.first
1110

modules/chat/public/views/partials/lib/queries/conversations/find_by_participant.liquid

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
endif
1111

1212
graphql r = 'modules/chat/conversations/search', limit: 1, id: id, participant_id: participant_id, include_messages: include_messages, messages_limit: 30
13-
include 'modules/community/helpers/handle_graphql_response', r: r, name: 'modules/chat/conversations/find_by_participant'
1413

1514
assign conversation = r.conversations.results.first
1615

modules/chat/public/views/partials/lib/queries/conversations/find_by_participants.liquid

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
endif
66

77
graphql r = 'modules/chat/conversations/search', limit: 1, participant_ids: participant_ids, include_messages: include_messages, messages_limit: 30
8-
include 'modules/community/helpers/handle_graphql_response', r: r, name: 'modules/chat/conversations/find_by_participants'
98

109
assign conversation = r.conversations.results.first
1110

modules/chat/public/views/partials/lib/queries/conversations/number_of_unread_by_participant.liquid

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
endif
66

77
graphql r = 'modules/chat/conversations/number_unread_by_participant', participant_id: participant_id
8-
include 'modules/community/helpers/handle_graphql_response', r: r, name: 'modules/chat/conversations/number_of_unread_by_participant'
98

109
return r.conversations.total_entries
1110
%}

modules/chat/public/views/partials/lib/queries/conversations/search.liquid

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{% liquid
22
assign page = page | to_positive_integer: 1
33
graphql r = 'modules/chat/conversations/search_by_message', limit: limit, page: page, participant_id: participant_id, message: message
4-
include 'modules/community/helpers/handle_graphql_response', r: r, name: 'modules/chat/conversations/search'
54

65
assign result = r.conversations
76
assign conversations = '[]' | parse_json

modules/chat/public/views/partials/lib/queries/conversations/search_by_participant.liquid

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
assign page = page | to_positive_integer: 1
88

99
graphql r = 'modules/chat/conversations/search', limit: limit, page: page, participant_id: participant_id
10-
include 'modules/community/helpers/handle_graphql_response', r: r, name: 'modules/chat/conversations/search'
1110

1211
assign result = r.conversations
1312
assign conversations = '[]' | parse_json

modules/chat/template-values.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
"name": "Pos Module Chat",
33
"machine_name": "chat",
44
"type": "module",
5-
"version": "0.0.9",
5+
"version": "1.0.0",
66
"dependencies": {
77
"components": "^1.1.3",
88
"core": "^1.0.0",
9-
"profile": "^1.0.0"
9+
"profile": "^1.0.0",
10+
"user": "^1.0.0"
1011
}
1112
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

modules/components/public/assets/components.css

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)