-
Notifications
You must be signed in to change notification settings - Fork 2
Feature Discussion
Deleting an object permanently can be challenging, because references to it may be used throughout the app. Special care must be taken if removing the references is not preferable (e.g. for users):
-
User
:- Referenced in
Meetling.users
,Editable.authors
(=Settings
,Meeting
,AgendaItem
) - Action: Anonymize, i.e set all fields to
None
and the name to e.g.Former user
- Referenced in
-
Meeting
:- Referenced in:
Meetling.meetings
- Remove from meetings along with all agenda items
- Referenced in:
-
AgendaItem
:- Referenced in:
Meeting.trashed_items
- Remove from trashed items
- Referenced in:
Trashed objects could be registered with a due time. When the due time is reached, a garbage collection could be triggered that performs the necessary actions for deletion.
To make the use of fetch a bit less verbose (e.g. include credentials and en/-decode JSON by default) introduce a small wrapper, like:
micro.call("POST", `/api/users/${this.userObject.id}`, {name: form.elements["name"].value}).then(...);
micro.call = function(method, url, args) {
return fetch(url, {method: method, credentials: "include", body: JSON.stringify(args)}).then(function(response) {
return response.json();
});
};
We could enhance printing by (sorted from lowest to highest effort):
- Tweaking the website to be better suited for printing - for example using the complete width of a page:
@media print {
.meetling-page-inside {
max-width: none;
}
}
- Adding a print button to the presentation mode (once it is implemented)
- Adding a dedicated print view
A more flexible input format for duration values would be nice. Possible options: 2:30
(looks like a time), 2h30m
(not easily localizable), 2 hours, 30min
(non-trivial to parse), two fields for hours and minutes (use case for hours is rare).
A) Inherit from input
(type=text/check
):
- (-) No custom content
- Effort:
- Implement only a few attributes/properties (
value
,readonly
, ...) - Disable superfluous attributes
- Implement only a few attributes/properties (
B) Wrap input
:
- (-) Form compatibility only via hidden
input
hack - Effort:
- Implement all attributes/properties (often transfer value to hidden
input
)
- Implement all attributes/properties (often transfer value to hidden
Details:
- Attributes/properties:
name
,value
,readonly
,required
,defaultValue
, ... - Superfluous attributes/properties:
type
,pattern
, ... - Depending on the type, some more attributes/properties are needed/superfluous:
placeholder
,min/max
, ...
Before printing text (in text emails, log output, ...), collapse white space, handle newline characters (depending on whether line breaks are allowed) and wrap it nicely. Maybe the textwrap module could be useful.
If there is one day the need for subpages, we could convert the action bar into a menu bar that mixes links and actions.
Cookies could be delivered with secure=True
and working links could be created for email
notifications.
- Require the admin to provide the full URL including scheme and deduce it from that
- Evaluate headers from the SSL proxy
- via hash, e.g.
#notification=foo
- via page attribute, e.g.
notification="foo"
- Log in automatically (implemented)
- Perform any action (e.g. like, edit, ...) instantly
- After the first action, ask the user once for their name (let others know who you are) and email address (for notifications)
class Meetling:
def prepare_login(self, email=None):
"""Create an one-time login code for either the current *user* or the user given by *email*.
If no user with *email* exists, a :exc:`ValueError` (``email_not_registered``) is raised.
The code should be transmitted to the user in a safe way. The code can then be used by
:meth:`login` to log in.
"""
user = self.user or self.users[self.r.hget('emails', email)]
login_code = randstr()
self.r.set(login_code, user.auth_secret)
self.r.expire(login_code, 24 * 60 * 60)
return login_code
def login(self, code=None):
"""
.. http:post:: /api/login
``{"code": null}``
Log in an :ref:`User` (device).
If *code* is given, log in an existing user with the login *code*. If the login fails, a
:exc:`ValueError` (``code_invalid``) is returned.
If no *code* is given, ...
"""
if code:
secret = self.app.r.get(code)
if not secret:
raise ValueError('invalid')
self.app.r.delete(code)
return self.authenticate(secret)
else:
# ...
Make it possible to create a follow-up meeting, for which some properties of the current meeting (e.g. description, list of subscribers, ...) are copied, new default values for some properties (e.g. time + one week) are proposed and the option to transfer some agenda items (think of items that have been delayed or that need the attention of a second meeting) is given.
By default the line will wrap between words if the title consists of multiple words.
.meetling-start-logo span {
white-space: nowrap;
}
{
'a': (str, [int]),
'b': {'c': str, 'd': {'e': int}}
}