diff --git a/lib/Coocook/Controller/Admin.pm b/lib/Coocook/Controller/Admin.pm index bcd4a98de7e56544ac39d8c73c44b49f17ec08b5..a3345b158022cbf9f081e1bb9b79fb567d529685 100644 --- a/lib/Coocook/Controller/Admin.pm +++ b/lib/Coocook/Controller/Admin.pm @@ -7,21 +7,7 @@ BEGIN { extends 'Coocook::Controller' } sub base : Chained('/base') PathPart('admin') CaptureArgs(0) { my ( $self, $c ) = @_; - my $admin_urls = $c->stash->{admin_urls}; - - my @items = ( - { url => $c->stash->{admin_url}, text => "Admin" }, - { url => $admin_urls->{faq}, text => "FAQ" }, - { url => $admin_urls->{organizations}, text => "Organizations" }, - { url => $admin_urls->{projects}, text => "Projects" }, - { url => $admin_urls->{recipes}, text => "Recipes" }, - { url => $admin_urls->{terms}, text => "Terms" }, - { url => $admin_urls->{users}, text => "Users" }, - ); - - $_->{url} or $_->{forbidden} = 1 for @items; - - $c->stash( submenu_items => \@items ); + $c->stash( on_admin_pages => 1 ); } sub index : GET HEAD Chained('base') PathPart('') Args(0) RequiresCapability('admin_view') { diff --git a/lib/Coocook/Controller/Dish.pm b/lib/Coocook/Controller/Dish.pm index 0a380a1fbc32bf7a17dd35deef35369eb0ac0dbb..c26a991c36c53a9666d8fcf90deb1d605c781128 100644 --- a/lib/Coocook/Controller/Dish.pm +++ b/lib/Coocook/Controller/Dish.pm @@ -16,7 +16,7 @@ Catalyst Controller. =cut -sub base : Chained('/project/submenu') PathPart('dish') CaptureArgs(1) { +sub base : Chained('/project/base') PathPart('dish') CaptureArgs(1) { my ( $self, $c, $id ) = @_; $c->stash( dish => $c->project->dishes->find( $id, { prefetch => [ 'meal', 'recipe' ] } ) diff --git a/lib/Coocook/Controller/Permission.pm b/lib/Coocook/Controller/Permission.pm index e8b6b5a91100414f04665f03ee36a30f6129d126..d9162f67cb8fa4b90c51d8c30c30dd96ede8f884 100644 --- a/lib/Coocook/Controller/Permission.pm +++ b/lib/Coocook/Controller/Permission.pm @@ -4,7 +4,7 @@ use Coocook::Base qw(Moose); BEGIN { extends 'Coocook::Controller' } -sub index : GET HEAD Chained('/project/submenu') PathPart('permissions') Args(0) +sub index : GET HEAD Chained('/project/base') PathPart('permissions') Args(0) RequiresCapability('view_project_permissions') { my ( $self, $c ) = @_; @@ -39,6 +39,9 @@ sub index : GET HEAD Chained('/project/submenu') PathPart('permissions') Args(0) my $projects_users = $c->project->projects_users->prefetch('user'); while ( my $project_user = $projects_users->next ) { + my $can_transfer_onership = + $c->has_capability( 'transfer_project_ownership', { permission => $project_user } ); + push @permissions, { role => $project_user->role, sort_key => $project_user->user->name_fc, @@ -51,8 +54,7 @@ sub index : GET HEAD Chained('/project/submenu') PathPart('permissions') Args(0) ? $c->project_uri( $self->action_for('edit'), $project_user->user->name ) : undef, - make_owner_url => - $c->has_capability( 'transfer_project_ownership', { permission => $project_user } ) + make_owner_url => $can_transfer_onership ? $c->project_uri( $self->action_for('make_owner'), $project_user->user->name ) : undef, @@ -60,6 +62,10 @@ sub index : GET HEAD Chained('/project/submenu') PathPart('permissions') Args(0) ? $c->project_uri( $self->action_for('revoke'), $project_user->user->name ) : undef, }; + + if ($can_transfer_onership) { + $c->stash( can_transfer_ownership => 1 ); + } } } diff --git a/lib/Coocook/Controller/Project.pm b/lib/Coocook/Controller/Project.pm index 1e6ecd03b8d915e837278ba0c53b0419e5254a20..8145f7649b8764456e21a22d3a498ab0142ebc1c 100644 --- a/lib/Coocook/Controller/Project.pm +++ b/lib/Coocook/Controller/Project.pm @@ -113,21 +113,7 @@ sub base : Chained('/base') PathPart('project') CaptureArgs(2) { } } -sub submenu : Chained('base') PathPart('') CaptureArgs(0) { - my ( $self, $c ) = @_; - - $c->stash( - submenu_items => [ - { text => "Show project", action => 'project/show' }, - { text => "Meals & Dishes", action => 'project/edit' }, - { text => "Permissions", action => 'permission/index' }, - { text => "Shop sections", action => 'shop_section/index' }, - { text => "Settings", action => 'project/settings' }, - ], - ); -} - -sub show : GET HEAD Chained('submenu') PathPart('') Args(0) RequiresCapability('view_project') { +sub show : GET HEAD Chained('base') PathPart('') Args(0) RequiresCapability('view_project') { my ( $self, $c ) = @_; my $days = $c->model('Plan')->project( $c->project ); @@ -143,6 +129,9 @@ sub show : GET HEAD Chained('submenu') PathPart('') Args(0) RequiresCapability(' $day->{url} = $c->project_uri( '/print/day', $date->year, $date->month, $date->day ); } + $c->stash->{project_urls}{settings} = $c->project_uri( $self->action_for('settings') ); + $c->stash->{project_urls}{permissions} = $c->project_uri('/permission/index'); + $c->stash( can_edit => !!$c->has_capability('edit_project'), can_unarchive => !!$c->has_capability('unarchive_project'), @@ -150,7 +139,7 @@ sub show : GET HEAD Chained('submenu') PathPart('') Args(0) RequiresCapability(' ); } -sub edit : GET HEAD Chained('submenu') PathPart('edit') Args(0) RequiresCapability('edit_project') { +sub edit : GET HEAD Chained('base') PathPart('edit') Args(0) RequiresCapability('edit_project') { my ( $self, $c ) = @_; my $default_date = DateTime->today; @@ -195,7 +184,7 @@ sub edit : GET HEAD Chained('submenu') PathPart('edit') Args(0) RequiresCapabili ); } -sub settings : GET HEAD Chained('submenu') PathPart('settings') Args(0) +sub settings : GET HEAD Chained('base') PathPart('settings') Args(0) RequiresCapability('view_project_settings') { my ( $self, $c ) = @_; diff --git a/lib/Coocook/Controller/PurchaseList.pm b/lib/Coocook/Controller/PurchaseList.pm index 301660e56698eadd82bc431bd1fc3d55b50cd554..81903f84d5610fea5ff82a011e7f886d32b80c24 100644 --- a/lib/Coocook/Controller/PurchaseList.pm +++ b/lib/Coocook/Controller/PurchaseList.pm @@ -40,13 +40,15 @@ sub index : GET HEAD Chained('/project/base') PathPart('purchase_lists') Args(0) $list->{date} = $lists->parse_date( $list->{date} ); - $list->{edit_url} = $c->project_uri( $self->action_for('edit'), $list->{id} ); - $list->{update_url} = $c->project_uri( $self->action_for('update'), $list->{id} ); + $list->{edit_url} = $c->project_uri( $self->action_for('edit'), $list->{id} ); + $list->{update_url} = $c->project_uri_if_permitted( $self->action_for('update'), $list->{id} ); $list->{make_default_url} = - !$list->{is_default} ? $c->project_uri( $self->action_for('make_default'), $list->{id} ) : undef; + !$list->{is_default} + ? $c->project_uri_if_permitted( $self->action_for('make_default'), $list->{id} ) + : undef; $list->{delete_url} = ( @lists == 1 or !$list->{is_default} ) - ? $c->project_uri( $self->action_for('delete'), $list->{id} ) + ? $c->project_uri_if_permitted( $self->action_for('delete'), $list->{id} ) : undef; } @@ -96,6 +98,14 @@ sub edit : GET HEAD Chained('base') PathPart('') Args(0) RequiresCapability('vie $dish->{url} = $c->project_uri( '/dish/edit', $dish->{id} ); } + $c->stash( can_edit => !!$c->has_capability('edit_project') ); + $c->json_stash( + list_permissions => { + can_edit => !!$c->has_capability('edit_project'), + is_archived => !!$c->project->archived, + }, + ); + $c->has_capability('edit_project') or return; diff --git a/lib/Coocook/Controller/Root.pm b/lib/Coocook/Controller/Root.pm index e6eb5b32ada34cc6273e5a850499d2a8a1ce1414..b8e4ab7fa0f60ea8a382a3307f309da4e2381df2 100644 --- a/lib/Coocook/Controller/Root.pm +++ b/lib/Coocook/Controller/Root.pm @@ -337,39 +337,6 @@ Attempt to render a view, if needed. sub end : ActionClass('RenderView') { my ( $self, $c ) = @_; - for my $item ( $c->stash->{submenu_items}->@* ) { - next if $item->{forbidden}; - next if $item->{url}; - - my $action = $item->{action}; - - my $capabilities = $self->action_for($action)->attributes->{RequiresCapability}; - - for my $capability (@$capabilities) { - if ( not $c->has_capability($capability) ) { - $item->{forbidden} = 1; - next; - } - } - - if ( $c->action ne $action ) { - if ( $action =~ m/ ^ (admin|settings) \/ /x ) { # TODO how to distinguish this in a generic way? - $item->{url} = $c->uri_for_action($action); - } - else { - if ( $c->project ) { - $item->{url} = $c->project_uri($action); - } - else { - $item->{forbidden} = 1; - } - } - } - } - - # remove subitems that have the 'forbidden' flag - $c->stash->{submenu_items}->@* = grep { not $_->{forbidden} } $c->stash->{submenu_items}->@*; - { my $errors = $c->stash->{errors}; my $status = $c->res->status; diff --git a/lib/Coocook/Controller/Settings.pm b/lib/Coocook/Controller/Settings.pm index 79505ea3b9f623134d9dd58845929f208499c301..68fdc4983c8f2aed5406a43f0d9690db62f84197 100644 --- a/lib/Coocook/Controller/Settings.pm +++ b/lib/Coocook/Controller/Settings.pm @@ -8,11 +8,11 @@ sub base : Chained('/base') PathPart('settings') CaptureArgs(0) { my ( $self, $c ) = @_; $c->stash( - submenu_items => [ - { action => 'settings/account', text => "Account" }, - { action => 'settings/organizations', text => "Organizations" }, - { action => 'settings/projects', text => "Projects" }, - ], + settings_urls => { + account => $c->uri_for_action_if_permitted('settings/account'), + organizations => $c->uri_for_action_if_permitted('settings/organizations'), + projects => $c->uri_for_action_if_permitted('settings/projects'), + }, ); } diff --git a/lib/Coocook/Helpers.pm b/lib/Coocook/Helpers.pm index 6b2d5538c59edccb94dc4c4d6694b4fc94118543..0d06c5774407a2a07d27231107cccf4acd7cd5b5 100644 --- a/lib/Coocook/Helpers.pm +++ b/lib/Coocook/Helpers.pm @@ -232,6 +232,40 @@ sub project_uri { ); } +=head2 $c->project_uri_if_permitted($action, @arguments, \%query_params?) + +Return URI for project-specific Catalyst action with the current project's C and C +plus any number of C<@arguments> and possibly C<\%query_params> if the current session has enough +capabilities to perform C<$action>. + + my $uri = $c->project_uri_if_permitted( '/purchase_list/update', $purchase_list->id, { key => 'value' } ); + # http://localhost/project/MyProject/purchase_list/42?key=value or undef if not enough capabilities + + my $uri = $c->project_uri( $self->action_for('update'), $purchase_list->id, { key => 'value' } ); + # the same + +=cut + +sub project_uri_if_permitted { + my $c = shift; + my $action = shift; + + my $project = $c->stash->{project} + or croak "Missing 'project' in stash"; + + my $fragment = ref $_[-1] eq 'SCALAR' ? pop @_ : undef; + + # if last argument is hashref that's the \%query_values argument + my $query = ref $_[-1] eq 'HASH' ? pop @_ : undef; + + return $c->uri_for_action_if_permitted( + $action, + [ $project->id, $project->url_name, @_ ], + $query || (), + $fragment || () + ); +} + sub project ($c) { $c->stash->{project} } =head2 $c->redirect_canonical_case( $args_index, $canonical_value ) diff --git a/root/common_templates/macros.tt b/root/common_templates/macros.tt index 4654ceb2598641ad416b13751c3e775731c9a701..741b419f0b96dec1a38514b75aacb62f3115fcd2 100644 --- a/root/common_templates/macros.tt +++ b/root/common_templates/macros.tt @@ -20,7 +20,7 @@ END; MACRO display_project(project, opts) BLOCK ~%] [% project.is_public ? 'public' : 'lock' %]  - [% project.name | html; + [%~ project.name | html; END; MACRO display_tag(tag) BLOCK ~%] @@ -107,4 +107,53 @@ length=items.size ~%] [% END %] +[%~ END; + +# Arguments for button and tooltip_button +# opts: +# - variant: optional, str - one of the bootstrap variants, default: primary +# - disabled: bool, optional - triggering the "disabled" HTML attribute, default: false +# - href: str, optional - if set the button is rendered as Tag with the given href instead of + [% button( { + text => (faq.in_storage ? 'Update' : 'Create') _ ' Entry', + attrs => { + type => 'submit', + }, + } ) %] diff --git a/root/templates/admin/faq/index.tt b/root/templates/admin/faq/index.tt index 81b6a053dccceb9006349962af9f06ac965ca8ce..66c410bdd892b5d52e0960d8fd275453b09da80a 100644 --- a/root/templates/admin/faq/index.tt +++ b/root/templates/admin/faq/index.tt @@ -14,13 +14,28 @@ USE Markdown; %] [% faq.question_md | markdown %] - edit + [% tooltip_button( { + icon => 'edit', + tooltip => { + content => 'Edit FAQ entry', + }, + href => faq.url, + button_classes => 'btn-sm', + } ) %] [% END %] - add + [% tooltip_button( { + variant => 'outline-primary', + icon => 'add', + tooltip => { + content => 'Create FAQ entry', + }, + href => new_faq_url, + container_classes => 'd-grid', + } ) %] diff --git a/root/templates/admin/terms/edit.tt b/root/templates/admin/terms/edit.tt index 463554c8ca39a71f9462de2d0f0db965bc917ef3..8afbe7db41fa697e002f1f4d9aa6b5da3ef7e84e 100644 --- a/root/templates/admin/terms/edit.tt +++ b/root/templates/admin/terms/edit.tt @@ -3,7 +3,7 @@

Valid from: - +

@@ -11,5 +11,12 @@
-

+
+ [% button( { + text => (terms.in_storage ? 'Update' : 'Create') _ ' terms', + attrs => { + type => 'submit', + }, + } ) %] +
diff --git a/root/templates/admin/terms/index.tt b/root/templates/admin/terms/index.tt index e7f4388b330d704f9921fef92ed5f81613832e6c..5918f923e3989c0173aafa35b710860fd6ac751d 100644 --- a/root/templates/admin/terms/index.tt +++ b/root/templates/admin/terms/index.tt @@ -5,22 +5,45 @@
[% IF item.edit_url %]
- + [% tooltip_button( { + variant => 'outline-dark', + icon => 'edit', + tooltip => { + content => 'Edit terms', + }, + attrs => { + type => 'submit', + }, + button_classes => 'btn-sm', + } ) %]
[% END; IF item.delete_url %]
- + [% tooltip_button( { + variant => 'outline-danger', + icon => 'delete_forever', + tooltip => { + content => 'Delete terms', + }, + attrs => { + type => 'submit', + }, + button_classes => 'btn-sm', + } ) %]
[% END %]
[% END; list(terms, 'term_item', { item_classes => 'd-flex gap-3 justify-content-between align-items-center parent'}) %] -
- add -
+[% tooltip_button( { + variant => 'outline-primary', + icon => 'add', + tooltip => { + content => 'Create new terms', + }, + href => new_url, + container_classes => 'd-grid mt-4', + button_classes => 'btn-no-square', +} ) %] diff --git a/root/templates/article/edit.tt b/root/templates/article/edit.tt index 7adab80d61e4dd99bc35767d5127c8f3bb41422b..f51d9afd082f47f49c28f45535b2042b661ef029 100644 --- a/root/templates/article/edit.tt +++ b/root/templates/article/edit.tt @@ -116,7 +116,12 @@ IF article; escape_title( 'Article', article.name ); ELSE; title="New Article";
- + [% button( { + text => (article ? 'Update' : 'Create'), + attrs => { + type => 'submit', + }, + } ) %] diff --git a/root/templates/article/index.tt b/root/templates/article/index.tt index eceb1194d0f11d47fc38d0d5765547d14ab05c36..bb9368163868c5783fb9d340bd1c928d521581c8 100644 --- a/root/templates/article/index.tt +++ b/root/templates/article/index.tt @@ -1,7 +1,13 @@ [% title = "Articles" %] [% new = BLOCK %] -

add New article

+

+ [% button( { + icon => 'add', + text => 'New article', + href => new_url, + } ) %] +

[% END; new %] [% WRAPPER table length=articles.size classes='align-middle' %] @@ -42,17 +48,22 @@ - [% IF article.delete_url %]
- + [% article_name = article.name | html; + tooltip_button( { + variant => 'outline-danger', + icon => 'delete_forever', + disabled => !article.delete_url, + tooltip => { + content => 'Delete ' _ article_name _ '', + disabled_content => 'This article is used in dishes/recipes', + }, + attrs => { + type => article.delete_url ? 'submit' : 'button', + }, + button_classes => 'btn-sm', + } ) %]
- [% ELSE %] - - [% END %] [% END %] diff --git a/root/templates/browse/recipe/import.tt b/root/templates/browse/recipe/import.tt index 275e8809ee8e068b38259687f1658805d6530ae6..b77551a51f8169564096f549eb7b7041400b108d 100644 --- a/root/templates/browse/recipe/import.tt +++ b/root/templates/browse/recipe/import.tt @@ -10,9 +10,14 @@
[% link_project(proj) %]
- + [% button( { + text => 'Import', + icon => 'east', + attrs => { + type => 'submit', + }, + icon_after_text => 1, + } ) %]
diff --git a/root/templates/browse/recipe/index.tt b/root/templates/browse/recipe/index.tt index 4b51a8865e8a93ca10282ebcbbecf07bf784b581..a4fd7b0a7a19dc7624d87b83b1aec131dd78a938 100644 --- a/root/templates/browse/recipe/index.tt +++ b/root/templates/browse/recipe/index.tt @@ -23,7 +23,17 @@ END %] [% IF item.import_url %]
- + [% tooltip_button( { + icon => 'east', + text => 'Import', + tooltip => { + content => 'Import this recipe into one of your projects', + }, + attrs => { + type => 'submit', + }, + icon_after_text => 1, + } ) %]
[% END; END; diff --git a/root/templates/browse/recipe/show.tt b/root/templates/browse/recipe/show.tt index 306bc0bd03e842e2af15e1038cbdec07bae9ca73..95f2f1cc6d0ab4acef2321ab96aeeb60de04744a 100644 --- a/root/templates/browse/recipe/show.tt +++ b/root/templates/browse/recipe/show.tt @@ -3,7 +3,12 @@ js_push_template_path(); css.push('/css/print.css') %] - +[% tooltip_button( { + icon => 'print', + tooltip => { content => 'Print' }, + attrs => { onclick => 'print()' }, + container_classes => 'd-inline-block my-3 no-print', +} ) %]
@@ -17,7 +22,17 @@ css.push('/css/print.css') %]

[% IF import_url %]
- + [% tooltip_button( { + icon => 'east', + text => 'Import', + tooltip => { + content => 'Import this recipe into one of your projects', + }, + attrs => { + type => 'submit', + }, + icon_after_text => 1, + } ) %]
[% END %]
@@ -31,7 +46,13 @@ css.push('/css/print.css') %]
- + [% button( { + text => 'Show', + icon => 'calculate', + attrs => { + type => 'submit', + }, + } ) %]
diff --git a/root/templates/dashboard.tt b/root/templates/dashboard.tt index c95272a86e431b79ad7c08a3b263e336399568ea..e0aa0b256667dedfb23952d02d91fd1733f554ab 100644 --- a/root/templates/dashboard.tt +++ b/root/templates/dashboard.tt @@ -16,7 +16,9 @@
- + [% button( { + text => 'Create project', + } ) %]
diff --git a/root/templates/dish/edit.tt b/root/templates/dish/edit.tt index d0872d66ae6e90c195de93c77eac82aab16be5d4..58ebfdcd5557778e2497c64a0b4ca01f0c8809cf 100644 --- a/root/templates/dish/edit.tt +++ b/root/templates/dish/edit.tt @@ -18,9 +18,14 @@ js.push('/js/tagAutocomplete.js');
- + [% button( { + variant => 'danger', + text => 'Delete', + icon => 'delete_forever', + attrs => { + type => 'submit', + }, + } ) %]
@@ -86,7 +91,12 @@ js.push('/js/tagAutocomplete.js');
- + [% button( { + text => 'Update dish', + attrs => { + type => 'submit', + }, + } ) %]
@@ -111,7 +121,12 @@ class="col-sm-12 py-3">
- + [% button( { + text => 'Recalculate values', + attrs => { + type => 'submit', + }, + } ) %]
diff --git a/root/templates/faq/index.tt b/root/templates/faq/index.tt index fb53d2bd671dde24ed8f4d944f092bdb3a2b40e5..96167fb897d93d13f85bb6a823b010d3e74a73d6 100644 --- a/root/templates/faq/index.tt +++ b/root/templates/faq/index.tt @@ -2,10 +2,12 @@ html_title = 'Frequently Asked Questions' %] [% IF admin_faq_url %] -
-
- Edit FAQ -
+
+ [% button( { + text => 'Edit FAQ', + variant => 'outline-primary', + href => admin_faq_url, + } ) %]
[% END; @@ -21,7 +23,16 @@ FOR faq IN faqs %] [% IF faq.edit_url %]
- + [% tooltip_button( { + icon => 'edit', + tooltip => { + content => 'Edit', + }, + container_classes => 'ms-1', + attrs => { + type => 'submit', + }, + } ) %]
[% END %]
diff --git a/root/templates/organization/members.tt b/root/templates/organization/members.tt index 3348f5afd314059829a6932ed679d0c8a3cbe202..9968c5db1ce623e88aafdc2659de78568e0aa611 100644 --- a/root/templates/organization/members.tt +++ b/root/templates/organization/members.tt @@ -31,7 +31,8 @@ has_admin = 0 %] [% END %] - + [%# We don't use the button macro here. Because when we would use the macro the styling would break %] + [% ELSE %] [% o_u.role %] @@ -42,12 +43,32 @@ has_admin = 0 %] [% IF o_u.transfer_ownership_url; has_admin = 1 %]
- + [% tooltip_button( { + variant => 'outline-secondary', + icon => 'sync_alt', + tooltip => { + content => 'Transfer ownership', + }, + attrs => { + type => 'submit', + }, + button_classes => 'btn-sm', + } ) %]
[% END %] [% IF o_u.remove_url %]
- + [% tooltip_button( { + variant => 'outline-danger', + icon => 'delete_forever', + tooltip => { + content => 'Remove', + }, + attrs => { + type => 'submit', + }, + button_classes => 'btn-sm', + } ) %]
[% END %] @@ -93,7 +114,12 @@ has_admin = 0 %]
- + [% button( { + text => 'Add', + attrs => { + type => 'submit', + }, + } ) %]
[% ELSE %] diff --git a/root/templates/organization/show.tt b/root/templates/organization/show.tt index e8eb8cd49f12d82fd2e9cec532962a8fed5d6e62..0718bce4f1838895b6c6002072e095cd388fb2f4 100644 --- a/root/templates/organization/show.tt +++ b/root/templates/organization/show.tt @@ -12,7 +12,12 @@ - + [% button( { + text => 'Change display name', + attrs => { + type => 'submit', + }, + } ) %] [% ELSE %]
@@ -35,7 +40,12 @@
- + [% button( { + text => 'Update description', + attrs => { + type => 'submit', + }, + } ) %] [% ELSE %] [% USE Markdown; organization.description_md | markdown %] @@ -56,15 +66,12 @@ BLOCK project_item ~%]

Members

- [% IF members_url %] - - manage_accounts Manage memberships - - [% ELSE %] - - manage_accounts Manage memberships - - [% END %] + [% button( { + text => 'Manage memberships', + icon => 'manage_accounts', + href => members_url, + disabled => members_url, + } ) %]
[% list(organizations_users, 'user_item', {list_classes => 'list-group-flush rounded'}) %] @@ -98,7 +105,13 @@ BLOCK project_item ~%]

Deleting an organization also removes all memberships and the organization’s permissions on projects.

- + [% button( { + variant => 'danger', + text => 'Delete organization', + attrs => { + type => 'submit', + }, + } ) %]
diff --git a/root/templates/print/day.tt b/root/templates/print/day.tt index 11da828739638297594351c9b98853bc65b830d7..d31cb15d685a1c780dea74fc7431cf5a6e8be468 100644 --- a/root/templates/print/day.tt +++ b/root/templates/print/day.tt @@ -1,6 +1,12 @@ [% css.push('/css/print.css') %] - +
+ [% tooltip_button( { + icon => 'print', + tooltip => { content => 'Print' }, + attrs => { onclick => 'print()' }, + } ) %] +
[% FOR meal IN meals %]

[% meal.name | html %]

diff --git a/root/templates/project/edit.tt b/root/templates/project/edit.tt index 2b42bb50552432269e17f790a3b0c621e994204e..8edc045510528af315172c830445065b9c1dbcf7 100644 --- a/root/templates/project/edit.tt +++ b/root/templates/project/edit.tt @@ -4,6 +4,14 @@ css_push_template_path(); js.push('/lib/coocook-web-components/dist/meals-dishes-editor/meals-dishes-editor.es.js'); %] +
+ [% tooltip_button( { + icon => 'edit_off', + href => project_urls.project, + tooltip => { content => 'Show' }, + } ) %] +
+
[% WRAPPER includes/infobox.tt %] diff --git a/root/templates/project/import.tt b/root/templates/project/import.tt index 1dcad3a8dd5abe8456d52658157de03ed5c2cacf..152ef155d7f477b0f692ae6eca69a5fd5b3acb2d 100644 --- a/root/templates/project/import.tt +++ b/root/templates/project/import.tt @@ -41,8 +41,14 @@ js_push_template_path() %] [% END %]
- - +
+ [% button( { + text => 'Import', + attrs => { + type => 'submit', + }, + } ) %] +
[% END %] diff --git a/root/templates/project/permissions.tt b/root/templates/project/permissions.tt index 7798a281d0129389abab3302715a539a9ae05c2e..ae5d4ab3cfd42008e56b0919a68f8bc065725955 100644 --- a/root/templates/project/permissions.tt +++ b/root/templates/project/permissions.tt @@ -10,13 +10,12 @@ has_admin = 0 %] User/Organization Role - - + [% FOR permission IN permissions %] - + [% IF permission.organization; link_organization(permission.organization); @@ -27,64 +26,91 @@ has_admin = 0 %] END %] - [% IF permission.edit_url %] -
-
-
+ [% IF permission.edit_url %] + +
-
-
- -
+ [% tooltip_button( { + icon => 'check', + tooltip => { content => 'Save' }, + attrs => { + 'type' => 'submit', + }, + container_classes => 'action-btn', + } ) %]
- [% ELSE %] + [% ELSE %] [% permission.role %] - [% END %] - - - [% IF permission.make_owner_url %] -
-
- -
-
- [% END %] + [% END %] - [% IF permission.revoke_url %] -
-
- -
-
- [% END %] +
+ [% IF permission.make_owner_url %] +
+ [% tooltip_button( { + variant => 'outline-primary', + icon => 'transfer_within_a_station', + tooltip => { content => 'Transfer ownership' }, + attrs => { + 'type' => 'submit', + 'onsubmit' => 'return confirm("Do you really want to transfer the project ownership? You cannot undo this action.");', + }, + button_classes => 'btn-sm', + } ) %] +
+ [% END; + IF permission.revoke_url %] +
+ [% tooltip_button( { + variant => 'outline-danger', + icon => 'delete_forever', + tooltip => { content => 'Revoke permission' }, + attrs => { + 'type' => 'submit', + }, + button_classes => 'btn-sm', + } ) %] +
+ [% END %] +
[% END %] - + public anyone [% project.is_public ? "viewer (project is public)" : "— (project is private)" %] - -
- [% IF project.is_public %] - - [% ELSE %] + + [% IF project.is_public %] + [% tooltip_button( { + variant => 'outline-warning', + icon => 'lock', + tooltip => { content => 'Make project private' }, + attrs => { + 'type' => 'submit', + }, + button_classes => 'btn-sm', + } ) %] + [% ELSE %] - - [% END %] + [% tooltip_button( { + variant => 'outline-warning', + icon => 'public', + tooltip => { content => 'Make project public' }, + attrs => { + 'type' => 'submit', + }, + button_classes => 'btn-sm', + } ) %] + [% END %]
+ @@ -125,7 +151,12 @@ has_admin = 0 %]
- + [% button( { + text => 'Add', + attrs => { + type => 'submit', + }, + } ) %]
[% ELSE %] diff --git a/root/templates/project/show.tt b/root/templates/project/show.tt index 7be8637390ad636b890fa05f4bf0ee71b99f6c29..350ab9acdf85d56e048a7d3a2bf5fde75ca81556 100644 --- a/root/templates/project/show.tt +++ b/root/templates/project/show.tt @@ -1,9 +1,38 @@ [% js_push_template_path(); css.push('/css/print.css'); -show_donate_infobox = 0; +show_donate_infobox = 0 %] -IF project.archived; +

[% project.name | html %]

+
+ [% tooltip_button( { + icon => 'edit', + href => project_urls.edit, + tooltip => { content => 'Edit project' }, + } ) %] + [% tooltip_button( { + icon => 'print', + tooltip => { content => 'Print' }, + attrs => { onclick => 'print()' }, + } ) %] + [% tooltip_button( { + icon => 'list', + href => project_urls.shop_sections, + tooltip => { content => 'Shop sections' }, + } ) %] + [% tooltip_button( { + icon => 'manage_accounts', + href => project_urls.permissions, + tooltip => { content => 'Project permissions' }, + } ) %] + [% tooltip_button( { + icon => 'settings', + href => project_urls.settings, + tooltip => { content => 'Project settings' }, + } ) %] +
+ +[% IF project.archived; show_donate_infobox = 1 %]
[% IF can_unarchive %] @@ -55,10 +84,6 @@ IF project.archived;
[% END %] -

[% project.name | html %]

- - -
[% USE Markdown; project.description | markdown %] @@ -71,9 +96,17 @@ IF project.archived; Meal Dishes -
- -
+ [% tooltip_button( { + variant => 'outline-primary', + icon => 'add', + tooltip => { content => 'Add extra column' }, + attrs => { + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#addCol', + }, + button_classes => 'btn-sm btn-no-square', + container_classes => 'd-grid', + } ) %] diff --git a/root/templates/purchase_list/_edit_table.tt b/root/templates/purchase_list/_edit_table.tt index dcf7037b319b454ed60dabf0d0df9bb90b7aa99e..bb3320066bf3646b4dc0c842144941dcaeb10e5c 100644 --- a/root/templates/purchase_list/_edit_table.tt +++ b/root/templates/purchase_list/_edit_table.tt @@ -48,7 +48,17 @@ [% display_unit( item.unit, {html=>1} ) %]
- + [% tooltip_button( { + variant => 'outline-primary', + icon => 'done', + tooltip => { + content => 'Update amount', + }, + attrs => { + type => 'submit', + }, + button_classes => 'ms-1 pl-form', + } ) %] [% ELSE; IF item.offset < 0; '⊖'; @@ -58,10 +68,20 @@ END; IF item.convertible_into.size %] -
+
[% FOREACH unit IN item.convertible_into %]
- + [% tooltip_button( { + variant => 'outline-secondary', + text => display_value_unit(unit.total, unit, {html=>1}), + tooltip => { + content => 'Convert to ' _ display_value_unit(unit.total, unit, {print=>1}), + }, + attrs => { + type => 'submit', + }, + button_classes => 'btn-sm', + } ) %]
[% END %]
@@ -125,7 +145,18 @@ [% IF item.update_offset_url %]
- + [% tooltip_button( { + variant => 'outline-danger', + icon => 'undo', + tooltip => { + content => 'Reset rounding', + }, + attrs => { + type => 'submit', + name => 'offset', + value => '0', + }, + } ) %]
[% END %] diff --git a/root/templates/purchase_list/edit.tt b/root/templates/purchase_list/edit.tt index 80c0eca1c2e720e89b351d39d73a425f619e66a7..f067940b2a1b4834907b35f84a651c0a78e645ca 100644 --- a/root/templates/purchase_list/edit.tt +++ b/root/templates/purchase_list/edit.tt @@ -9,23 +9,47 @@ js.push('/lib/coocook-web-components/dist/autocomplete/autocomplete.es.js'); js_push_template_path(); %] - -[% IF purchase_lists.size > 1 %] - - -[% END %] - - +
+ [% tooltip_button( { + icon => 'print', + tooltip => { content => 'Print' }, + attrs => { onclick => 'print()' }, + } ); -
+ IF purchase_lists.size > 1; + tooltip_button( { + disabled => 1, + icon => 'drive_file_move', + text => 'Move items/ingredients to other purchase list', + tooltip => { + content => 'Move selected items/ingredients to different purchase list', + disabled_content => 'No items/ingredients selected to move', + }, + attrs => { + id => 'move-btn', + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#move-items', + }, + } ); + END; + + tooltip_button( { + disabled => 1, + icon => 'move_to_inbox', + text => 'Assign articles to shop section', + tooltip => { + content => 'Assign selected articles to a shop section', + disabled_content => 'No articles selected to assign', + }, + attrs => { + id => 'assign-btn', + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#assign-articles', + }, + } ) %] +
+ +
[% INCLUDE purchase_list/_edit_table.tt %]
diff --git a/root/templates/purchase_list/index.tt b/root/templates/purchase_list/index.tt index 3bf5a0cfb126a10637f66098b8741c7118c4815e..d77603849de15d812c150143c7b496e20c519aab 100644 --- a/root/templates/purchase_list/index.tt +++ b/root/templates/purchase_list/index.tt @@ -5,9 +5,21 @@ js_push_template_path(); BLOCK new_list %] -
- -
+ [% tooltip_button( { + variant => 'outline-primary', + icon => 'add', + disabled => !create_url, + tooltip => { + content => 'Create ' _ (purchase_lists.size > 0 ? 'another' : 'a') _ ' purchase list', + line_through => 1, + }, + attrs => { + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#addList', + }, + container_classes => 'd-grid', + button_classes => 'btn-no-square', + } ) %] [% END %] @@ -41,50 +53,62 @@ BLOCK new_list %] [% purchase_list.ingredients_count %]
- - - + [% tooltip_button( { + variant => 'outline-dark', + disabled => !purchase_list.update_url, + icon => 'edit', + tooltip => { content => 'Rename purchase list', line_through => 1 }, + attrs => { + 'data-url' => purchase_list.update_url, + 'data-name' => purchase_list.name, + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#updateList', + }, + button_classes => 'btn-sm update-trigger', + } ); - [% IF purchase_lists.size > 1; - IF purchase_list.make_default_url %] + IF purchase_lists.size > 1 %]
- + [% tooltip_button( { + variant => 'outline-dark', + disabled => !purchase_list.make_default_url, + icon => 'shopping_cart_checkout', + tooltip => { + content => purchase_list.is_default ? 'Is already the default purchase list' : 'Make purchase list the default purchase list', + line_through => purchase_list.is_default ? 0 : 1, + }, + attrs => { + type => 'submit', + }, + button_classes => 'btn-sm', + } ) %]
- [% ELSE %] - - - - [% END; - END; + [% END; - IF purchase_list.delete_url; - IF is_in_use %] - - - - [% ELSE %] -
- -
- [% END; + button_classes = [ 'btn-sm' ]; + button_classes.push('delete-trigger') IF is_in_use; - ELSE %] - - - - [% END %] + tooltip_button( { + button_classes => button_classes, + variant => 'outline-danger', + disabled => !purchase_list.delete_url || (purchase_lists.size > 1 && purchase_list.is_default), + icon => 'delete_forever', + tooltip => { + content => purchase_lists.size > 1 && purchase_list.is_default ? 'Can’t delete default purchase list' : 'Delete purchase list', + line_through => purchase_lists.size > 1 && purchase_list.is_default ? 0 : 1, + }, + attrs => is_in_use ? { + 'data-url' => purchase_list.delete_url, + 'data-name' => purchase_list.name, + 'data-count' => purchase_list.items_count, + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#delete-list', + } : { + form => 'delete-list-form-' _ purchase_list.id, + type => 'submit', + }, + } ) %] +
diff --git a/root/templates/recipe/edit.tt b/root/templates/recipe/edit.tt index db31b14014ec3073e02b1a6a61ac4ec1b42a4ba5..f696f79dd3f9ece8ad70561385c26c96c0a56ac7 100644 --- a/root/templates/recipe/edit.tt +++ b/root/templates/recipe/edit.tt @@ -10,22 +10,50 @@ IF import_url %]
- + [% + button_label = 'Used in ' _ dishes.size _ ' dish' _ (dishes.size != 1 ? 'es' : ''); + button( { + text => button_label, + attrs => { + 'data-bs-toggle' => 'collapse', + 'data-bs-target' => '#usage', + 'aria-expanded' => 'false', + 'aria-controls' => 'usage', + }, + button_classes => 'dropdown-toggle align-items-center', + disabled => dishes.size == 0, + } ) + %]
[% IF public_url %] - - - - [% END; - IF import_url %]
- + [% button( { + text => 'Share link', + href => public_url, + variant => 'secondary', + attrs => { + 'data-bs-toggle' => 'collapse', + 'data-bs-target' => '#usage', + 'aria-expanded' => 'false', + 'aria-controls' => 'usage', + }, + } ) %]
- [% END %] + [% END; + IF import_url; + tooltip_button( { + variant => 'secondary', + text => 'Import into another project', + icon => 'east', + icon_after_text => 1, + tooltip => { content => 'Import this recipe into another one of your projects' }, + attrs => { + type =>'submit', + form => 'import', + }, + container_classes => 'btn-group col-xxl-3 col-md-4 col-sm-6', + } ); + END %]
[% IF dishes.size > 0 %] @@ -86,7 +114,12 @@ IF import_url %]
- + [% button( { + text => 'Update recipe', + attrs => { + type => 'submit', + }, + } ) %]
diff --git a/root/templates/recipe/importable_recipes.tt b/root/templates/recipe/importable_recipes.tt index 27aa33085a48487d52cc8268ef030282144ff77d..1033f0667775f31b4ac0171222b42ce704098e00 100644 --- a/root/templates/recipe/importable_recipes.tt +++ b/root/templates/recipe/importable_recipes.tt @@ -13,9 +13,17 @@ [% IF recipe.import_url %]
- + [% + project_name = project.name | html; + tooltip_button( { + text => 'Import', + icon => 'east', + tooltip => { content => 'Import this recipe into project "' _ project_name _ '"' }, + attrs => { + type => 'submit', + }, + } ) + %]
[% END %] diff --git a/root/templates/recipe/index.tt b/root/templates/recipe/index.tt index dbcb46de0d661659d52cebab8f3197f83b52bd85..34662f37c12734cdae842fea0b0e217ea4c4cffb 100644 --- a/root/templates/recipe/index.tt +++ b/root/templates/recipe/index.tt @@ -4,12 +4,25 @@ js_push_template_path(); new = BLOCK %]

- - - east Import recipe - +[% + tooltip_button( { + icon => 'add', + text => 'New recipe', + tooltip => { content => 'Add new recipe' }, + attrs => { + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#create-recipe-modal', + }, + } ); + + tooltip_button( { + icon => 'east', + text => 'Import recipe', + variant => 'secondary', + href => import_recipe_url, + tooltip => { content => 'Import recipe' }, + } ); +%]

[% END; new %] @@ -34,13 +47,30 @@ new = BLOCK %]
- + [% + recipe_name = recipe.name | html; + tooltip_button( { + icon => 'file_copy', + variant => 'outline-dark', + tooltip => { content => 'Duplicate "' _ recipe_name _ '"' }, + attrs => { + 'data-name' => recipe_name, + 'data-url' => recipe.duplicate_url, + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#duplicate-recipe-modal', + }, + button_classes => 'btn-sm duplicate-trigger', + } ) + %]
- + [% button( { + icon => 'delete_forever', + variant => 'outline-danger', + attrs => { + type => 'submit', + }, + button_classes => 'btn-sm', + } ) %]
diff --git a/root/templates/session/login.tt b/root/templates/session/login.tt index 7a607ec485178a20b9729074740c024efd29431b..467997ec51078e7c132835e84380e9225b9aa15b 100644 --- a/root/templates/session/login.tt +++ b/root/templates/session/login.tt @@ -20,7 +20,9 @@ - + [% button( { + text => 'Sign in', + } ) %] diff --git a/root/templates/settings/account.tt b/root/templates/settings/account.tt index 4d00b4a35e18e9b3a146974fe143f33e83de00e7..c1b2fdc9a2abdd5db2514c13d2ee2d981ddb7f33 100644 --- a/root/templates/settings/account.tt +++ b/root/templates/settings/account.tt @@ -5,19 +5,21 @@ js.push('/lib/zxcvbn.js'); %] [% IF confirm_email_change_url %] -
-
-
- You can confirm to change your email address to - [% user.new_email_fc | html %] - -
-
-
+
+ You can confirm to change your email address to + [% user.new_email_fc | html %] + [% button( { + text => 'Confirm email change', + } ) %] +
[% END %]

- View your profile + [% button( { + text => 'View your profile', + variant => 'outline-primary', + href => profile_url, + } ) %]

@@ -41,7 +43,9 @@ js.push('/lib/zxcvbn.js');
- + [% button( { + text => 'Change display name', + } ) %] @@ -67,7 +71,10 @@ js.push('/lib/zxcvbn.js'); - + [% button( { + text => 'Change password', + button_classes => 'mb-2', + } ) %]
If you don’t know your current password anymore, you can @@ -90,12 +97,12 @@ js.push('/lib/zxcvbn.js');
[% IF user.new_email_fc %] -
-
- You’ve requested change to [% user.new_email_fc | html %] - at [% display_datetime(user.token_created, {short=>1}) %] UTC - -
+ + You’ve requested change to [% user.new_email_fc | html %] + at [% display_datetime(user.token_created, {short=>1}) %] UTC + [% button( { + text => 'Cancel', + } ) %]
[% END %] @@ -105,7 +112,9 @@ js.push('/lib/zxcvbn.js');
- + [% button( { + text => 'Change email address', + } ) %]
diff --git a/root/templates/settings/organizations.tt b/root/templates/settings/organizations.tt index 8c5759c4de43a8881954ab668c74c6389bb57a1d..6dba001bad6ed3909163f5a7d01c157a78e79eff 100644 --- a/root/templates/settings/organizations.tt +++ b/root/templates/settings/organizations.tt @@ -14,7 +14,12 @@ BLOCK new_org %]
- + [% button( { + text => 'Create organization', + attrs => { + name => 'create', + }, + } ) %]
@@ -28,21 +33,33 @@ BLOCK user_item %] [% link_organization(item.organization) %] ([% item.role %]) [% IF item.leave_url %]
- + [% button( { + text => 'Leave organization', + icon => 'logout', + variant => 'outline-danger', + } ) %]
-[% ELSE %] - -[% END; +[% ELSE; + tooltip_button( { + text => 'Leave organization', + icon => 'logout', + variant => 'outline-danger', + tooltip => { + content => 'You are the owner of this organization', + }, + disabled => 1, + button_classes => 'action-btn', + } ); +END; END; IF organizations_users.size > 0 %]

Before you can leave an organization you need to transfer organization ownership to another organization member.

- [% list(organizations_users, 'user_item', {item_classes => 'd-flex gap-3 justify-content-between align-items-center flex-wrap parent'}) %] + [% list(organizations_users, 'user_item', { + list_classes => 'mb-3', + item_classes => 'd-flex gap-3 justify-content-between align-items-center flex-wrap parent', + }) %] [% ELSE %]

You are not member of any organization yet.

[% END; diff --git a/root/templates/shop_section/index.tt b/root/templates/shop_section/index.tt index e879e9a3bb48b8d1eeba53ad4fb884bd4604a580..0917613bdf252a19bc1ff5b06f445d1c739c1903 100644 --- a/root/templates/shop_section/index.tt +++ b/root/templates/shop_section/index.tt @@ -5,9 +5,19 @@ js_push_template_path(); BLOCK new_section %] -
- -
+ [% tooltip_button( { + variant => 'outline-primary', + icon => 'add', + tooltip => { + content => 'Create shop section', + }, + attrs => { + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#add-section', + }, + container_classes => 'd-grid', + button_classes => 'btn-no-square', + } ) %] [% END %] @@ -28,20 +38,33 @@ BLOCK new_section %] [% section.articles_count %]
- - [% IF section.delete_url %] -
- + [% + section_name = section.name | html; + tooltip_button( { + variant => 'outline-dark', + icon => 'edit', + tooltip => { content => 'Rename shop section', line_through => 1 }, + attrs => { + 'data-url' => section.update_url, + 'data-name' => section_name, + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#update-section', + }, + button_classes => 'btn-sm update', + } ) + %] + + [% tooltip_button( { + variant => 'outline-danger', + icon => 'delete_forever', + disabled => !section.delete_url, + tooltip => { + content => 'Delete shop section', + disabled_content => numerus(section.articles_count, 'article', 'articles') _ ' are assigned to this shop section', + }, + button_classes => 'btn-sm', + } ) %]
- [% ELSE %] - - [% END %]
diff --git a/root/templates/tag/edit.tt b/root/templates/tag/edit.tt index d500619e415273b0cb72052fe82769b5bf3b39ab..23310e3d14999ea6c25e17cae39955a5a24f0ccf 100644 --- a/root/templates/tag/edit.tt +++ b/root/templates/tag/edit.tt @@ -10,20 +10,26 @@ js_push_template_path() %]

- - [% IF is_in_use %] - - [% ELSE %] + [% button( { + text => 'Edit', + icon => 'edit', + attrs => { + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#edit-tag', + }, + button_classes => 'update', + } ) %]
- + [% button( { + text => 'Delete', + icon => 'delete', + disabled => is_in_use, + variant => 'danger', + attrs => { + id => 'delete-btn', + }, + } ) %]
- [% END %]
diff --git a/root/templates/tag/index.tt b/root/templates/tag/index.tt index 23964924d9d115e924baa1c3245bcab779aedc2c..02c73c14a5e86e4f7e990650a3588639a3ed95ad 100644 --- a/root/templates/tag/index.tt +++ b/root/templates/tag/index.tt @@ -1,63 +1,83 @@ [% title = "Tags"; -js_push_template_path() %] +js_push_template_path(); -

- - -

+BLOCK new_element %] + +
+[% + button( { + text => 'New Tag', + icon => 'add', + attrs => { + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#add-tag', + }, + } ); + button( { + text => 'New Tag group', + icon => 'add', + attrs => { + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#add-tg', + }, + } ); +%] +
+[% END; + +PROCESS new_element; -[% FOR group IN groups %] +FOR group IN groups %]

Tag Group [% group.name | html %]

- - - [% IF group.tags.size %] -
- -
- [% ELSE %] + [% + group_name = group.name | html; + group_comment = group.comment | html; + tooltip_button( { + variant => 'outline-dark', + icon => 'add', + tooltip => { + content => 'Add tag to tag group '_ group_name, + }, + attrs => { + 'data-id' => group.id, + 'data-name' => group_name, + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#add-to-group', + }, + button_classes => 'btn-sm atg', + } ); + tooltip_button( { + variant => 'outline-dark', + icon => 'edit', + tooltip => { + content => 'Edit tag group '_ group_name, + }, + attrs => { + 'data-url' => group.update_url, + 'data-name' => group_name, + 'data-comment' => group_comment, + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#tg-edit', + }, + button_classes => 'btn-sm edit-tg', + } ) + %]
- + [% tooltip_button( { + variant => 'outline-danger', + icon => 'delete', + disabled => group.tags.size, + tooltip => { + content => 'Delete tag group '_ group_name, + disabled_content => "Can't delete tag group which contains tags", + }, + button_classes => 'btn-sm', + } ) %]
- [% END %]
@@ -83,18 +103,11 @@ js_push_template_path() %] [% END %]
-[% END %] +[% END; -

- - -

+PROCESS new_element; -[% WRAPPER includes/infobox.tt %] +WRAPPER includes/infobox.tt %] Tags are keywords that can be attached to recipes, dishes and articles. They can be used to filter them during search or to highlight important aspects.

diff --git a/root/templates/terms/show.tt b/root/templates/terms/show.tt index 9f829f1192566717f67ab893e15a53b30c05c2cc..d18758b922004225d7b1832c075535d7c056846a 100644 --- a/root/templates/terms/show.tt +++ b/root/templates/terms/show.tt @@ -2,11 +2,11 @@
[% IF previous_url %] - + chevron_left [% ELSE %] - + chevron_left [% END %] @@ -15,11 +15,11 @@ ' until ' _ display_date( terms.valid_until, {html=>1} ) IF terms.valid_until %]

[% IF next_url %] - + chevron_right [% ELSE %] - + chevron_right [% END %] diff --git a/root/templates/unit/edit.tt b/root/templates/unit/edit.tt index 583985fcaf7e7d665ca9ce246cee44fd3217a0f5..2c2141bcfb6707a78281e8c4c2b4f05dbde7e49b 100644 --- a/root/templates/unit/edit.tt +++ b/root/templates/unit/edit.tt @@ -14,7 +14,9 @@ END %]
- + [% button( { + text => 'Update', + } ) %]

Conversions

@@ -40,7 +42,10 @@ END %]
- + [% button( { + text => 'Add', + button_classes => 'btn-sm', + } ) %]
@@ -53,7 +58,7 @@ END %]
1 [% unit.long_name | html %] is equal to
[% IF conversion.update_url %] -
+
[% ELSE; @@ -62,13 +67,23 @@ END %] [% conversion.long_name | html %]
- [% IF conversion.update_url %] - - [% END %] + [% IF conversion.update_url; + button( { + text => 'Update', + button_classes => 'btn-sm', + attrs => { + form => 'update-conversion-to-unit-' _ conversion.id, + }, + } ); + END; - [% IF conversion.delete_url %] + IF conversion.delete_url %]
- + [% button( { + text => 'Delete', + variant => 'danger', + button_classes => 'btn-sm', + } ) %]
[% END %] [% ELSE %] diff --git a/root/templates/unit/index.tt b/root/templates/unit/index.tt index ad0a6ff456bdb5a1626e364c798bd5c73b6f54c7..e99acf51e2556fd02cf3ddda34c23bac50cc7ebf 100644 --- a/root/templates/unit/index.tt +++ b/root/templates/unit/index.tt @@ -4,9 +4,14 @@ js_push_template_path(); new = BLOCK %]

- + [% button( { + text => 'New unit', + icon => 'add', + attrs => { + 'data-bs-toggle' => 'modal', + 'data-bs-target' => '#create-unit-modal', + }, + } ) %]

[% END; new %] @@ -47,17 +52,18 @@ new = BLOCK %] [% END; IF loop.first %] - [% IF unit.delete_url %]
- + [% tooltip_button( { + icon => 'delete', + variant => 'outline-danger', + disabled => !unit.delete_url, + tooltip => { + content => 'Delete unit', + disabled_content => 'This is used for dish/recipe ingredients or purchase list items', + }, + button_classes => 'btn-sm', + } ) %]
- [% ELSE %] - - [% END %] [% END %] diff --git a/root/templates/user/recover.tt b/root/templates/user/recover.tt index 69e808dd658f73deb99bca8607d56295771b1f0a..d156d24377b9987e0479b6b9e9d026d0cc35dc5d 100644 --- a/root/templates/user/recover.tt +++ b/root/templates/user/recover.tt @@ -14,7 +14,10 @@
- + + [% button( { + text => 'Send recovery link', + } ) %] diff --git a/root/templates/user/register.tt b/root/templates/user/register.tt index 4b133ed08d52e2121f123277db6c5836fe7fa266..c989dff982820a67b90e4aad24c92f3d70f89283 100644 --- a/root/templates/user/register.tt +++ b/root/templates/user/register.tt @@ -51,7 +51,10 @@ IF terms %] By clicking [% label %] you accept our terms as of [% display_date(terms.valid_from, {html=>1}) %]. [% END %] You will receive an email with a web link to verify your email address. - + + [% button( { + text => label, + } ) %] diff --git a/root/templates/user/reset_password.tt b/root/templates/user/reset_password.tt index bdab62d3ac76b3e0648709ce6c3cd36cdfa75184..43adcc6e51730f19dec76d225dee467d6decb251 100644 --- a/root/templates/user/reset_password.tt +++ b/root/templates/user/reset_password.tt @@ -23,7 +23,10 @@ js.push('/lib/zxcvbn.js');
- + + [% button( { + text => 'Reset password', + } ) %] diff --git a/root/templates/user/show.tt b/root/templates/user/show.tt index bab048182a1d3cf02492add8be5bf169b7da2c9f..0969b2970f57ef016b999884262c63696e60efb1 100644 --- a/root/templates/user/show.tt +++ b/root/templates/user/show.tt @@ -1,13 +1,23 @@ [% escape_title( 'User', user_object.display_name ) %]

- [% IF my_settings_url %] - edit Edit your profile - [% END %] + [% IF my_settings_url; + button( { + text => 'Edit your profile', + icon => 'edit', + variant => 'outline-primary', + href => my_settings_url, + } ); + END %] - [% IF profile_admin_url %] - supervisor_account View profile as admin - [% END %] + [% IF profile_admin_url; + button( { + text => 'View profile as admin', + icon => 'supervisor_account', + variant => 'outline-secondary', + href => profile_admin_url, + } ); + END %]

Registered: [% display_date(user_object.created) %]

diff --git a/root/templates/wrapper.tt b/root/templates/wrapper.tt index 3ff1b4c686a9f27c2de6d2d511e3024cbabb0b72..97490c18d2374d77f702cd2f735732a7de5e34b7 100644 --- a/root/templates/wrapper.tt +++ b/root/templates/wrapper.tt @@ -57,59 +57,73 @@
-
-