View | Details | Raw Unified | Return to bug 10190
Collapse All | Expand All

(-)a/admin/circulation_triggers.pl (+45 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2024 PTFS Europe Ltd
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use CGI        qw ( -utf8 );
23
use C4::Auth   qw( get_template_and_user );
24
use C4::Output qw( output_html_with_http_headers );
25
26
my $query = CGI->new;
27
28
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
29
    {
30
        template_name => "admin/circulation_triggers.tt",
31
        query         => $query,
32
        type          => "intranet",
33
    }
34
);
35
36
my $letters = C4::Letters::GetLettersAvailableForALibrary(
37
    {
38
        branchcode => undef,
39
        module     => "circulation",
40
    }
41
);
42
43
$template->param( letters => $letters );
44
45
output_html_with_http_headers $query, $cookie, $template->output;
(-)a/debian/templates/apache-shared-intranet.conf (+1 lines)
Lines 24-29 RewriteRule ^/cgi-bin/koha/erm/.*$ /cgi-bin/koha/erm/erm.pl [PT] Link Here
24
RewriteCond %{REQUEST_URI} !^/cgi-bin/koha/preservation/.*.pl$
24
RewriteCond %{REQUEST_URI} !^/cgi-bin/koha/preservation/.*.pl$
25
RewriteRule ^/cgi-bin/koha/preservation/.*$ /cgi-bin/koha/preservation/home.pl [PT]
25
RewriteRule ^/cgi-bin/koha/preservation/.*$ /cgi-bin/koha/preservation/home.pl [PT]
26
RewriteRule ^/cgi-bin/koha/admin/record_sources(.*)?$ /cgi-bin/koha/admin/record_sources.pl$1 [PT]
26
RewriteRule ^/cgi-bin/koha/admin/record_sources(.*)?$ /cgi-bin/koha/admin/record_sources.pl$1 [PT]
27
RewriteRule ^/cgi-bin/koha/admin/circulation_triggers(.*)?$ /cgi-bin/koha/admin/circulation_triggers.pl$1 [PT]
27
28
28
Alias "/api" "/usr/share/koha/api"
29
Alias "/api" "/usr/share/koha/api"
29
<Directory "/usr/share/koha/api">
30
<Directory "/usr/share/koha/api">
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt (+4 lines)
Lines 99-104 Link Here
99
                    <dt><a href="/cgi-bin/koha/admin/smart-rules.pl">Circulation and fine rules</a></dt>
99
                    <dt><a href="/cgi-bin/koha/admin/smart-rules.pl">Circulation and fine rules</a></dt>
100
                    <dd>Define circulation and fine rules for combinations of libraries, patron categories, and item types</dd>
100
                    <dd>Define circulation and fine rules for combinations of libraries, patron categories, and item types</dd>
101
                [% END %]
101
                [% END %]
102
                [% IF ( CAN_user_tools_edit_notice_status_triggers ) %]
103
                    <dt><a href="/cgi-bin/koha/admin/circulation_triggers">Circulation triggers</a></dt>
104
                    <dd>Define triggers for circulation notices</dd>
105
                [% END %]
102
                [% IF ( CAN_user_parameters_manage_patron_attributes ) %]
106
                [% IF ( CAN_user_parameters_manage_patron_attributes ) %]
103
                    <dt><a href="/cgi-bin/koha/admin/patron-attr-types.pl">Patron attribute types</a></dt>
107
                    <dt><a href="/cgi-bin/koha/admin/patron-attr-types.pl">Patron attribute types</a></dt>
104
                    <dd>Define extended attributes (identifiers and statistical categories) for patron records</dd>
108
                    <dd>Define extended attributes (identifiers and statistical categories) for patron records</dd>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/circulation_triggers.tt (+42 lines)
Line 0 Link Here
1
[% USE raw %]
2
[% USE To %]
3
[% USE Asset %]
4
[% USE KohaDates %]
5
[% USE TablesSettings %]
6
[% USE AuthorisedValues %]
7
[% SET footerjs = 1 %]
8
[% PROCESS 'i18n.inc' %]
9
[% INCLUDE 'doc-head-open.inc' %]
10
<title>[% FILTER collapse %]
11
    [% t("Circulation triggers") | html %] &rsaquo;
12
    [% t("Administration") | html %] &rsaquo;
13
    [% t("Koha") | html %]
14
[% END %]</title>
15
[% INCLUDE 'doc-head-close.inc' %]
16
</head>
17
18
<body id="circulation_triggers" class="circulation_triggers">
19
[% WRAPPER 'header.inc' %]
20
    [% INCLUDE 'prefs-admin-search.inc' %]
21
[% END %]
22
23
<div id="__app"> <!-- this is closed in intranet-bottom.inc -->
24
25
[% MACRO jsinclude BLOCK %]
26
    [% INCLUDE 'calendar.inc' %] <!-- FIXME: this shouldn't be needed -->
27
    [% INCLUDE 'datatables.inc' %]
28
    [% INCLUDE 'columns_settings.inc' %]
29
    [% INCLUDE 'js-patron-format.inc' %]
30
    [% INCLUDE 'js-date-format.inc' %]
31
32
    <script>
33
34
        const letters = [% To.json(letters) | $raw %];
35
36
    </script>
37
38
    [% Asset.js("js/vue/dist/admin/circulation_triggers.js") | $raw %]
39
40
[% END %]
41
42
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Admin/CirculationTriggers/Main.vue (+65 lines)
Line 0 Link Here
1
<template>
2
    <div>
3
        <div id="sub-header">
4
            <Breadcrumbs />
5
            <Help />
6
        </div>
7
        <div class="main container-fluid">
8
            <div class="row">
9
                <div class="col-sm-10 col-sm-push-2">
10
                    <main>
11
                        <Dialog />
12
                        <router-view />
13
                    </main>
14
                </div>
15
16
                <div class="col-sm-2 col-sm-pull-10"></div>
17
            </div>
18
        </div>
19
    </div>
20
</template>
21
22
<script>
23
import Breadcrumbs from "../../Breadcrumbs.vue"
24
import Help from "../../Help.vue"
25
import Dialog from "../../Dialog.vue"
26
import "vue-select/dist/vue-select.css"
27
import { inject } from "vue"
28
29
export default {
30
    setup() {
31
        const circRulesStore = inject("circRulesStore")
32
        letters.unshift({
33
            name: "No letter",
34
            code: "",
35
        })
36
        circRulesStore.letters = letters
37
38
        return {
39
            letters,
40
        }
41
    },
42
    components: {
43
        Breadcrumbs,
44
        Dialog,
45
        Help,
46
    },
47
}
48
</script>
49
50
<style>
51
form .v-select {
52
    display: inline-block;
53
    background-color: white;
54
    width: 30%;
55
}
56
57
.v-select,
58
input:not([type="submit"]):not([type="search"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]),
59
textarea {
60
    border-color: rgba(60, 60, 60, 0.26);
61
    border-width: 1px;
62
    border-radius: 4px;
63
    min-width: 30%;
64
}
65
</style>
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/circulation-rules-api-client.js (+38 lines)
Line 0 Link Here
1
import HttpClient from "./http-client";
2
3
export class CircRuleAPIClient extends HttpClient {
4
    constructor() {
5
        super({
6
            baseURL: "/api/v1/",
7
        });
8
    }
9
10
    get circRules() {
11
        return {
12
            getAll: (query, params, headers) =>
13
                this.getAll({
14
                    endpoint: "circulation_rules",
15
                    query,
16
                    params,
17
                    headers,
18
                }),
19
            update: rule =>
20
                this.put({
21
                    endpoint: "circulation_rules",
22
                    body: rule,
23
                }),
24
            count: (query = {}) =>
25
                this.count({
26
                    endpoint:
27
                        "circulation_rules?" +
28
                        new URLSearchParams({
29
                            _page: 1,
30
                            _per_page: 1,
31
                            ...(query && { q: JSON.stringify(query) }),
32
                        }),
33
                }),
34
        };
35
    }
36
}
37
38
export default CircRuleAPIClient;
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/admin/circulation_triggers.ts (+57 lines)
Line 0 Link Here
1
import { createApp } from "vue";
2
import { createPinia } from "pinia";
3
import { createWebHistory, createRouter } from "vue-router";
4
5
import { library } from "@fortawesome/fontawesome-svg-core";
6
import {
7
    faPlus,
8
    faMinus,
9
    faPencil,
10
    faTrash,
11
    faSpinner,
12
} from "@fortawesome/free-solid-svg-icons";
13
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
14
import vSelect from "vue-select";
15
import { useNavigationStore } from "../../stores/navigation";
16
import { useMainStore } from "../../stores/main";
17
import { useCircRulesStore } from "../../stores/circulation-rules";
18
import routesDef from "../../routes/admin/circulation_triggers";
19
20
library.add(faPlus, faMinus, faPencil, faTrash, faSpinner);
21
22
const pinia = createPinia();
23
const navigationStore = useNavigationStore(pinia);
24
const mainStore = useMainStore(pinia);
25
const circRulesStore = useCircRulesStore(pinia);
26
const { removeMessages } = mainStore;
27
const { setRoutes } = navigationStore;
28
const routes = setRoutes(routesDef);
29
30
const router = createRouter({
31
    history: createWebHistory(),
32
    linkExactActiveClass: "current",
33
    routes,
34
});
35
36
import App from "../../components/Admin/CirculationTriggers/Main.vue";
37
import i18n from "../../i18n";
38
39
const app = createApp(App);
40
41
const rootComponent = app
42
    .use(i18n)
43
    .use(pinia)
44
    .use(router)
45
    .component("font-awesome-icon", FontAwesomeIcon)
46
    .component("v-select", vSelect);
47
48
app.config.unwrapInjectedRef = true;
49
app.provide("mainStore", mainStore);
50
app.provide("navigationStore", navigationStore);
51
app.provide("circRulesStore", circRulesStore);
52
app.mount("#__app");
53
54
router.beforeEach(to => {
55
    navigationStore.$patch({ current: to.matched, params: to.params || {} });
56
    removeMessages(); // This will actually flag the messages as displayed already
57
});
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/routes/admin/circulation_triggers.js (+47 lines)
Line 0 Link Here
1
import { markRaw } from "vue";
2
import { $__ } from "../../i18n";
3
4
import CirculationTriggersList from "../../components/Admin/CirculationTriggers/CirculationTriggersList.vue";
5
import CirculationTriggersFormAdd from "../../components/Admin/CirculationTriggers/CirculationTriggersFormAdd.vue";
6
7
export default {
8
    title: $__("Administration"),
9
    path: "",
10
    href: "/cgi-bin/koha/admin/admin-home.pl",
11
    is_base: true,
12
    is_default: true,
13
    children: [
14
        {
15
            title: $__("Circulation triggers"),
16
            path: "/cgi-bin/koha/admin/circulation_triggers",
17
            children: [
18
                {
19
                    path: "",
20
                    name: "CirculationTriggersList",
21
                    component: markRaw(CirculationTriggersList),
22
                    title: $__("Home"),
23
                    children: [
24
                        {
25
                            path: "add",
26
                            name: "CirculationTriggersFormAdd",
27
                            component: markRaw(CirculationTriggersFormAdd),
28
                            title: $__("Add new trigger"),
29
                            meta: {
30
                                showModal: true,
31
                            },
32
                        },
33
                        {
34
                            path: "edit",
35
                            name: "CirculationTriggersFormEdit",
36
                            component: markRaw(CirculationTriggersFormAdd),
37
                            title: $__("Edit trigger"),
38
                            meta: {
39
                                showModal: true,
40
                            },
41
                        },
42
                    ],
43
                },
44
            ],
45
        },
46
    ],
47
};
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/circulation-rules.js (+49 lines)
Line 0 Link Here
1
import { defineStore } from "pinia";
2
3
export const useCircRulesStore = defineStore("circRules", {
4
    state: () => ({
5
        letters: [],
6
    }),
7
    actions: {
8
        splitCircRulesByTriggerNumber(rules) {
9
            const ruleSuffixes = ["delay", "notice", "mtt", "restrict"];
10
            let numberOfTabs = 1;
11
            const rulesPerTrigger = rules.reduce((acc, rule) => {
12
                const regex = /overdue_(\d+)_delay/g;
13
                const numberOfTriggers = Object.keys(rule).filter(key =>
14
                    regex.test(key)
15
                ).length;
16
                numberOfTabs = this.setNumberOfTabs(
17
                    numberOfTriggers,
18
                    numberOfTabs
19
                );
20
                const triggerNumbers = Array.from(
21
                    { length: numberOfTriggers },
22
                    (_, i) => i + 1
23
                );
24
                triggerNumbers.forEach(i => {
25
                    const ruleCopy = JSON.parse(JSON.stringify(rule));
26
                    const rulesToDelete = triggerNumbers.filter(
27
                        num => num !== i
28
                    );
29
                    ruleSuffixes.forEach(suffix => {
30
                        rulesToDelete.forEach(number => {
31
                            delete ruleCopy[`overdue_${number}_${suffix}`];
32
                        });
33
                    });
34
                    ruleCopy.triggerNumber = i;
35
                    acc.push(ruleCopy);
36
                });
37
                return acc;
38
            }, []);
39
40
            return { numberOfTabs, rulesPerTrigger };
41
        },
42
        setNumberOfTabs(triggerCount, tabCount) {
43
            if (triggerCount > tabCount) {
44
                return Array.from({ length: triggerCount }, (_, i) => i + 1);
45
            }
46
            return tabCount;
47
        },
48
    },
49
});
(-)a/webpack.config.js (-1 / +1 lines)
Lines 8-13 module.exports = { Link Here
8
    erm: "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/erm.ts",
8
    erm: "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/erm.ts",
9
    preservation: "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/preservation.ts",
9
    preservation: "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/preservation.ts",
10
    "admin/record_sources": "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/admin/record_sources.ts",
10
    "admin/record_sources": "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/admin/record_sources.ts",
11
    "admin/circulation_triggers": "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/admin/circulation_triggers.ts",
11
  },
12
  },
12
  output: {
13
  output: {
13
    filename: "[name].js",
14
    filename: "[name].js",
14
- 

Return to bug 10190