Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optionally enable/disable features on contact types #227

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ To use the User Management Tool with your CHT project, you'll need to create a n
`contact_types.contact_properties` | Array<ConfigProperty> | Defines the attributes which are collected and set on the user's primary contact doc. See [ConfigProperty](#ConfigProperty).
`contact_types.deactivate_users_on_replace` | boolean | Controls what should happen to the defunct contact and user documents when a user is replaced. When `false`, the contact and user account will be deleted. When `true`, the contact will be unaltered and the user account will be assigned the role `deactivated`. This allows for account restoration.
`contact_types.hint` | string | Provide a brief hint or description to clarify the expected input for the property.
`contact_types.feature_flags` | Array | A list of features to enable for this contact type. Acceptable values are `create`, `replace-contact` and `move`. All features are enabled by default
`logoBase64` | Image in base64 | Logo image for your project

#### ConfigProperty
Expand Down
36 changes: 35 additions & 1 deletion src/config/chis-ke/config.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ export type ContactType = {
contact_type: string;
contact_friendly?: string;
user_role: string[];
username_from_place: boolean;
username_from_place?: boolean;
hierarchy: HierarchyConstraint[];
replacement_property: ContactProperty;
place_properties: ContactProperty[];
contact_properties: ContactProperty[];
deactivate_users_on_replace: boolean;
deactivate_users_on_replace?: boolean;
hint?: string;
feature_flags?: string[];
};

export type HierarchyConstraint = {
Expand Down
2 changes: 2 additions & 0 deletions src/lib/remote-place-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { RemotePlace, ChtApi } from './cht-api';
import { Config, ContactType, HierarchyConstraint } from '../config';
import { Validation } from './validation';
import RemotePlaceCache from './remote-place-cache';
import assert from 'assert';

type RemotePlaceMap = { [key: string]: RemotePlace };

Expand Down Expand Up @@ -111,6 +112,7 @@ export default class RemotePlaceResolver {

function getFuzzFunction(place: Place, hierarchyLevel: HierarchyConstraint, contactType: ContactType) {
const fuzzingProperty = hierarchyLevel.level === 0 ? contactType.replacement_property : hierarchyLevel;
assert(fuzzingProperty);
if (fuzzingProperty.type === 'generated') {
throw Error(`Invalid configuration: hierarchy properties cannot be of type "generated".`);
}
Expand Down
24 changes: 17 additions & 7 deletions src/liquid/app/nav.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,20 @@
</a>
<div class="navbar-dropdown">
{% for placeType in contactTypes %}
<div class="navbar-item">
<b>{{placeType.friendly}}</b>
</div>
<a class="navbar-item" href="/add-place?type={{ placeType.name }}&op=new">Create New</a>
<a class="navbar-item" href="/add-place?type={{ placeType.name }}&op=replace">Replace Existing</a>
<a class="navbar-item" href="/add-place?type={{ placeType.name }}&op=bulk">Upload from CSV</a>
{% if placeType.feature_flags == undefined or placeType.feature_flags contains "create" or placeType.feature_flags contains "replace-contact" %}
<div class="navbar-item">
<b>{{placeType.friendly}}</b>
</div>
{%endif%}
{% if placeType.feature_flags == undefined or placeType.feature_flags contains "create" %}
<a class="navbar-item" href="/add-place?type={{ placeType.name }}&op=new">Create New</a>
{%endif%}
{% if placeType.feature_flags == undefined or placeType.feature_flags contains "replace-contact" %}
<a class="navbar-item" href="/add-place?type={{ placeType.name }}&op=replace">Replace Existing</a>
{%endif%}
{% if placeType.feature_flags == undefined or placeType.feature_flags contains "create" %}
<a class="navbar-item" href="/add-place?type={{ placeType.name }}&op=bulk">Upload from CSV</a>
{%endif%}
{% endfor%}
</div>
</div>
Expand All @@ -35,7 +43,9 @@
</a>
<div class="navbar-dropdown">
{% for placeType in contactTypes %}
<a class="navbar-item" href="/move/{{ placeType.name }}">Move {{placeType.friendly}}</a>
{% if placeType.feature_flags == undefined or placeType.feature_flags contains "move" %}
<a class="navbar-item" href="/move/{{ placeType.name }}">Move {{placeType.friendly}}</a>
{%endif%}
{% endfor%}
</div>
</div>
Expand Down
16 changes: 12 additions & 4 deletions src/liquid/place/directive_1_get_started.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@
<span class="material-symbols-outlined">add</span> Add {{contactType.friendly}}
</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="/add-place?type={{ contactType.name }}&op=new">Create New</a>
<a class="navbar-item" href="/add-place?type={{ contactType.name }}&op=replace">Replace Existing</a>
<a class="navbar-item" href="/add-place?type={{ contactType.name }}&op=bulk">Upload from CSV</a>
<a class="navbar-item" href="/move/{{ contactType.name }}">Move</a>
{% if contactType.feature_flags == undefined or contactType.feature_flags contains "create" %}
<a class="navbar-item" href="/add-place?type={{ contactType.name }}&op=new">Create New</a>
{%endif%}
{% if contactType.feature_flags == undefined or contactType.feature_flags contains "replace-contact" %}
<a class="navbar-item" href="/add-place?type={{ contactType.name }}&op=replace">Replace Existing</a>
{%endif%}
{% if contactType.feature_flags == undefined or contactType.feature_flags contains "create" %}
<a class="navbar-item" href="/add-place?type={{ contactType.name }}&op=bulk">Upload from CSV</a>
{%endif%}
{% if contactType.feature_flags == undefined or contactType.feature_flags contains "move" %}
<a class="navbar-item" href="/move/{{ contactType.name }}">Move</a>
{%endif%}
</div>
</div>
</div>
Expand Down
40 changes: 21 additions & 19 deletions src/liquid/place/list.html
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
<div id="place_list">
{% for contactType in contactTypes %}
<div id="{{contactType.name}}" class="mb-6">
<h2 class="title is-4">{{contactType.friendly}}</h2>
{% if contactType.places.length > 0 %}
<table
id="table_places"
class="table is-fullwidth is-striped is-hoverable"
>
{% include "components/table_header.html" contactType=contactType %}
<tbody>
{% for place in contactType.places %}
{% include "components/place_item.html" %}
{% endfor%}
</tbody>
</table>
{% else %}
<div class="notification is-white">
<i>No Results</i>
</div>
{% endif %}
{% if contactType.feature_flags == undefined or contactType.feature_flags contains "create" or contactType.feature_flags contains "replace-contact" %}
<div id="{{contactType.name}}" class="mb-6">
<h2 class="title is-4">{{contactType.friendly}}</h2>
{% if contactType.places.length > 0 %}
<table
id="table_places"
class="table is-fullwidth is-striped is-hoverable"
>
{% include "components/table_header.html" contactType=contactType %}
<tbody>
{% for place in contactType.places %}
{% include "components/place_item.html" %}
{% endfor%}
</tbody>
</table>
{% else %}
<div class="notification is-white">
<i>No Results</i>
</div>
{% endif %}
{%endif%}
{% endfor %}
</div>
22 changes: 12 additions & 10 deletions src/liquid/place/list_lazy.html
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
<div id="place_list" hx-trigger="load" hx-get="/app/list" hx-target="this" hx-swap="outerHTML">
{% for contactType in contactTypes %}
<div id="{{contactType.name}}" class="mb-6">
<h2 class="title is-4">{{contactType.friendly}}</h2>
<div>
<table id="table_places" class="table is-fullwidth is-striped is-hoverable">
{% include "components/table_header.html" contactType=contactType %}
</table>
<div class="container p-6 is-flex is-justify-content-center is-align-content-center">
<img src="/public/spinner.gif" alt="Loading data" />
</div>
</div>
{% if contactType.feature_flags == undefined or contactType.feature_flags contains "create" or contactType.feature_flags contains "replace-contact" %}
<div id="{{contactType.name}}" class="mb-6">
<h2 class="title is-4">{{contactType.friendly}}</h2>
<div>
<table id="table_places" class="table is-fullwidth is-striped is-hoverable">
{% include "components/table_header.html" contactType=contactType %}
</table>
<div class="container p-6 is-flex is-justify-content-center is-align-content-center">
<img src="/public/spinner.gif" alt="Loading data" />
</div>
</div>
{%endif%}
{% endfor %}
</div>
</div>
7 changes: 7 additions & 0 deletions src/routes/add-place.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ export default async function addPlace(fastify: FastifyInstance) {
? Config.getContactType(queryParams.type)
: contactTypes[contactTypes.length - 1];
const op = queryParams.op || 'new';
if (contactType.feature_flags) {
if ((op === 'new' && !contactType.feature_flags.includes('create')) ||
(op === 'replace' && !contactType.feature_flags.includes('replace-contact'))) {
resp.code(404).type('text/html').send('Not Found');
return;
}
}
const tmplData = {
view: 'add',
logo: Config.getLogoBase64(),
Expand Down
4 changes: 4 additions & 0 deletions src/routes/move.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export default async function sessionCache(fastify: FastifyInstance) {
const contactTypes = Config.contactTypes();

const contactType = Config.getContactType(placeType);
if (contactType.feature_flags && !contactType.feature_flags.includes('move')) {
resp.code(404).type('text/html').send('Not Found');
return;
}
const tmplData = {
view: 'move',
op: 'move',
Expand Down
Loading