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

(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/cities.tt (-187 / +4 lines)
Lines 69-203 Link Here
69
    <div class="row">
69
    <div class="row">
70
        <div class="col-sm-10 col-sm-push-2">
70
        <div class="col-sm-10 col-sm-push-2">
71
            <main>
71
            <main>
72
72
                  <div id="cities"></div>
73
[% FOR m IN messages %]
74
    <div class="dialog [% m.type | html %]">
75
        [% SWITCH m.code %]
76
        [% CASE 'error_on_update' %]
77
            <span>An error occurred when updating this city. Perhaps it already exists.</span>
78
        [% CASE 'error_on_insert' %]
79
            <span>An error occurred when adding this city. The city id might already exist.</span>
80
        [% CASE 'error_on_delete' %]
81
            <span>An error occurred when deleting this city. Check the logs.</span>
82
        [% CASE 'success_on_update' %]
83
            <span>City updated successfully.</span>
84
        [% CASE 'success_on_insert' %]
85
            <span>City added successfully.</span>
86
        [% CASE 'success_on_delete' %]
87
            <span>City deleted successfully.</span>
88
        [% CASE 'already_exists' %]
89
            <span>This city already exists.</span>
90
        [% CASE %]
91
            <span>[% m.code | html %]</span>
92
        [% END %]
93
    </div>
94
[% END %]
95
96
[% IF op == 'add_form' %]
97
    [% IF city %]
98
        <h1>Modify a city</h1>
99
    [% ELSE %]
100
        <h1>New city</h1>
101
    [% END %]
102
103
    <form action="/cgi-bin/koha/admin/cities.pl" name="Aform" method="post" class="validated">
104
        <input type="hidden" name="op" value="add_validate" />
105
        <input type="hidden" name="cityid" value="[% city.cityid | html %]" />
106
107
        <fieldset class="rows">
108
            <ol>
109
                [% IF city %]
110
                    <li><span class="label">City ID: </span>[% city.cityid | html %]</li>
111
                [% END %]
112
                <li>
113
                    <label for="city_name" class="required">City: </label>
114
                    <input type="text" name="city_name" id="city_name" size="80" maxlength="100" value="[% city.city_name | html %]" required="required" class="required" /> <span class="required">Required</span>
115
                </li>
116
                <li>
117
                    <label for="city_state">State: </label>
118
                    <input type="text" name="city_state" id="city_state" size="80" maxlength="100" value="[% city.city_state | html %]" />
119
                </li>
120
                <li>
121
                    <label for="city_zipcode" class="required">ZIP/Postal code: </label>
122
                    <input type="text" name="city_zipcode" id="city_zipcode" size="20" maxlength="20" value="[% city.city_zipcode | html %]" required="required" class="required" /> <span class="required">Required</span>
123
                </li>
124
                <li>
125
                    <label for="city_country">Country: </label>
126
                    <input type="text" name="city_country" id="city_country" size="80" maxlength="100" value="[% city.city_country | html %]" />
127
                </li>
128
            </ol>
129
        </fieldset>
130
131
        <fieldset class="action">
132
            <input type="submit" value="Submit" />
133
            <a class="cancel" href="/cgi-bin/koha/admin/cities.pl">Cancel</a>
134
        </fieldset>
135
    </form>
136
[% END %]
137
138
[% IF op == 'delete_confirm' %]
139
    <div class="dialog alert">
140
        <h1>Delete city "[% city.city_name | html %]?"</h1>
141
        <table>
142
            <tr><th>City id</th>
143
                <td>[% city.cityid | html %]</td>
144
            </tr>
145
            <tr><th>City</th>
146
                <td>[% city.city_name | html %]</td>
147
            </tr>
148
            <tr><th>State</th>
149
                <td>[% city.city_state | html %]</td>
150
            </tr>
151
            <tr><th>ZIP/Postal code</th>
152
                <td>[% city.city_zipcode | html %]</td>
153
            </tr>
154
            <tr><th>Country</th>
155
                <td>[% city.city_country | html %]</td>
156
            </tr>
157
        </table>
158
        <form action="/cgi-bin/koha/admin/cities.pl" method="post">
159
            <input type="hidden" name="op" value="delete_confirmed" />
160
            <input type="hidden" name="cityid" value="[% city.cityid | html %]" />
161
            <button type="submit" class="approve"><i class="fa fa-fw fa-check"></i> Yes, delete</button>
162
        </form>
163
        <form action="/cgi-bin/koha/admin/cities.pl" method="get">
164
            <button type="submit" class="deny"><i class="fa fa-fw fa-remove"></i> No, do not delete</button>
165
        </form>
166
    </div>
167
[% END %]
168
169
[% IF op == 'list' %]
170
171
    <div id="toolbar" class="btn-toolbar">
172
        <a class="btn btn-default" id="newcity" href="/cgi-bin/koha/admin/cities.pl?op=add_form"><i class="fa fa-plus"></i> New city</a>
173
    </div>
174
175
    <h1>Cities</h1>
176
    [% IF city_name_filter %]
177
        Searching: [% city_name_filter | html %]
178
    [% END %]
179
180
    [% IF cities_count > 0 %]
181
        <div class="table_cities_table_controls"></div>
182
        <table id="table_cities">
183
            <thead>
184
                <tr>
185
                    <th>City ID</th>
186
                    <th>City</th>
187
                    <th>State</th>
188
                    <th>ZIP/Postal code</th>
189
                    <th>Country</th>
190
                    <th data-class-name="actions noExport">Actions</th>
191
                </tr>
192
            </thead>
193
        </table>
194
    [% ELSE %]
195
        <div class="dialog message">
196
            There are no cities defined. <a href="/cgi-bin/koha/admin/cities.pl?op=add_form">Create a new city</a>.
197
        </div>
198
    [% END %]
199
[% END %]
200
201
            </main>
73
            </main>
202
        </div> <!-- /.col-sm-10.col-sm-push-2 -->
74
        </div> <!-- /.col-sm-10.col-sm-push-2 -->
203
75
Lines 213-221 Link Here
213
    [% INCLUDE 'datatables.inc' %]
85
    [% INCLUDE 'datatables.inc' %]
214
    [% INCLUDE 'columns_settings.inc' %]
86
    [% INCLUDE 'columns_settings.inc' %]
215
    <script>
87
    <script>
216
217
        var table_settings = [% TablesSettings.GetTableSettings( 'admin', 'cities', 'table_cities', 'json' ) | $raw %];
88
        var table_settings = [% TablesSettings.GetTableSettings( 'admin', 'cities', 'table_cities', 'json' ) | $raw %];
218
        $(document).ready(function() {
219
            var cities_table_url = '/api/v1/cities?';
89
            var cities_table_url = '/api/v1/cities?';
220
90
221
        [% IF city_name_filter %]
91
        [% IF city_name_filter %]
Lines 226-287 Link Here
226
            };
96
            };
227
            cities_table_url += 'q='+ encodeURIComponent(JSON.stringify(city_name_filter));
97
            cities_table_url += 'q='+ encodeURIComponent(JSON.stringify(city_name_filter));
228
        [% END %]
98
        [% END %]
229
230
            var cities_table = $("#table_cities").kohaTable({
231
                "ajax": {
232
                    "url": cities_table_url
233
                },
234
                "order": [[ 1, "asc" ]],
235
                "columnDefs": [ {
236
                    "targets": [0,1,2,3,4],
237
                    "render": function (data, type, row, meta) {
238
                        if ( type == 'display' ) {
239
                            return data.escapeHtml();
240
                        }
241
                        return data;
242
                    }
243
                } ],
244
                "columns": [
245
                    {
246
                        "data": "city_id",
247
                        "searchable": true,
248
                        "orderable": true
249
                    },
250
                    {
251
                        "data": "name",
252
                        "searchable": true,
253
                        "orderable": true
254
                    },
255
                    {
256
                        "data": "state",
257
                        "searchable": true,
258
                        "orderable": true
259
                    },
260
                    {
261
                        "data": "postal_code",
262
                        "searchable": true,
263
                        "orderable": true
264
                    },
265
                    {
266
                        "data": "country",
267
                        "searchable": true,
268
                        "orderable": true
269
                    },
270
                    {
271
                        "data": function( row, type, val, meta ) {
272
273
                            var result = '<a class="btn btn-default btn-xs" role="button" href="/cgi-bin/koha/admin/cities.pl?op=add_form&amp;cityid='+ encodeURIComponent(row.city_id) +'"><i class="fa fa-pencil" aria-hidden="true"></i> '+_("Edit")+'</a>'+"\n";
274
                            result += '<a class="btn btn-default btn-xs" role="button" href="/cgi-bin/koha/admin/cities.pl?op=delete_confirm&amp;cityid='+ encodeURIComponent(row.city_id) +'"><i class="fa fa-trash" aria-hidden="true"></i> '+_("Delete")+'</a>';
275
                            return result;
276
277
                        },
278
                        "searchable": false,
279
                        "orderable": false
280
                    }
281
                ]
282
            }, table_settings, 1);
283
284
        });
285
    </script>
99
    </script>
100
    [% Asset.js("js/vue/dist/main.js") %]
101
    [% Asset.js("js/vue/dist/runtime.js") %]
102
286
[% END %]
103
[% END %]
287
[% INCLUDE 'intranet-bottom.inc' %]
104
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/js/datatables.js (-4 / +4 lines)
Lines 511-520 jQuery.fn.dataTable.ext.errMode = function(settings, note, message) { Link Here
511
    $.fn.kohaTable = function(options, table_settings, add_filters, default_filters) {
511
    $.fn.kohaTable = function(options, table_settings, add_filters, default_filters) {
512
        var settings = null;
512
        var settings = null;
513
513
514
        if ( add_filters ) {
515
            $(this).find('thead tr').clone(true).appendTo( $(this).find('thead') );
516
        }
517
518
        if(options) {
514
        if(options) {
519
            if(!options.criteria || ['contains', 'starts_with', 'ends_with', 'exact'].indexOf(options.criteria.toLowerCase()) === -1) options.criteria = 'contains';
515
            if(!options.criteria || ['contains', 'starts_with', 'ends_with', 'exact'].indexOf(options.criteria.toLowerCase()) === -1) options.criteria = 'contains';
520
            options.criteria = options.criteria.toLowerCase();
516
            options.criteria = options.criteria.toLowerCase();
Lines 846-853 jQuery.fn.dataTable.ext.errMode = function(settings, note, message) { Link Here
846
842
847
        if ( add_filters ) {
843
        if ( add_filters ) {
848
            var table_dt = table.DataTable();
844
            var table_dt = table.DataTable();
845
846
            $(this).find('thead tr').clone().appendTo( $(this).find('thead') );
847
849
            $(this).find('thead tr:eq(1) th').each( function (i) {
848
            $(this).find('thead tr:eq(1) th').each( function (i) {
850
                var is_searchable = table_dt.settings()[0].aoColumns[i].bSearchable;
849
                var is_searchable = table_dt.settings()[0].aoColumns[i].bSearchable;
850
                $(this).removeClass('sorting');
851
                if ( is_searchable ) {
851
                if ( is_searchable ) {
852
                    let input_type = 'input';
852
                    let input_type = 'input';
853
                    if ( $(this).data('filter') ) {
853
                    if ( $(this).data('filter') ) {
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/Cities.vue (+64 lines)
Line 0 Link Here
1
<template>
2
    <Toolbar v-if="op=='list'" @switch-view="switchView"/>
3
    <b-alert v-if="message" variant="success" show>{{message}}</b-alert>
4
    <b-alert v-if="error" variant="warning" show>{{error}}</b-alert>
5
    <List v-if="op=='list'" @set-current-city-id="setCurrentCityID" @switch-view="switchView" @set-error="setError"/>
6
    <AddForm v-if="op=='add-form'" :city_id=city_id @city-created="cityCreated" @city-updated="cityUpdated" @set-error="setError" @switch-view="switchView"/>
7
    <ConfirmDeleteForm v-if="op=='confirm-delete-form'" :city_id=city_id @city-deleted="cityDeleted" @switch-view="switchView"/>
8
</template>
9
10
<script>
11
import Toolbar from "./components/CitiesToolbar.vue";
12
import List from "./components/CitiesList.vue";
13
import AddForm from "./components/CitiesFormAdd.vue";
14
import ConfirmDeleteForm from "./components/CitiesFormConfirmDelete.vue";
15
16
import {reactive, computed} from "vue";
17
18
export default {
19
    data() {
20
        return {city_id: null, op: 'list', message: null, error: null}
21
    },
22
    methods: {
23
        switchView(view) {
24
            this.message = null
25
            this.error = null
26
            this.op = view
27
            if (view == 'list' )
28
                this.city_id = null;
29
        },
30
        cityCreated() {
31
            this.message = "City created"
32
            this.error = null
33
            this.city_id = null
34
            this.op = 'list'
35
        },
36
        cityUpdated() {
37
            this.message = "City updated"
38
            this.error = null
39
            this.city_id = null
40
            this.op = 'list'
41
        },
42
        cityDeleted() {
43
            this.message = "City deleted"
44
            this.error = null
45
            this.city_id = null
46
            this.op = 'list'
47
        },
48
        setCurrentCityID(city_id){
49
            this.city_id = city_id
50
        },
51
        setError(error){
52
            this.message = null
53
            this.error = "Something went wrong: " + error
54
        },
55
    },
56
    components: {
57
        Toolbar,
58
        List,
59
        AddForm,
60
        ConfirmDeleteForm,
61
    },
62
    emits:['set-error'],
63
};
64
</script>
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/components/CitiesButtonDelete.vue (+9 lines)
Line 0 Link Here
1
<template>
2
    <button variant="default" size="sm">Delete</button>
3
</template>
4
5
<script>
6
export default {
7
    name: "CitiesButtonDelete"
8
}
9
</script>
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/components/CitiesButtonEdit.vue (+9 lines)
Line 0 Link Here
1
<template>
2
    <button variant="default" size="sm">Edit</button>
3
</template>
4
5
<script>
6
export default {
7
    name: "CitiesButtonEdit",
8
}
9
</script>
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/components/CitiesFormAdd.vue (+137 lines)
Line 0 Link Here
1
<template>
2
    <h2 v-if="city.city_id">Edit city</h2>
3
    <h2 v-else>New city</h2>
4
    <div>
5
        <b-form @submit="onSubmit">
6
            <b-form-group
7
                id="city_name"
8
                label="City name:"
9
                label-for="city_name"
10
                label-cols="4"
11
                label-cols-lg="2"
12
            >
13
                <b-form-input
14
                    id="city_name"
15
                    v-model="city.name"
16
                    placeholder="City name"
17
                    required
18
                ></b-form-input>
19
            </b-form-group>
20
            <b-form-group
21
                id="city_state"
22
                label="State:"
23
                label-for="city_state"
24
                label-cols="4" label-cols-lg="2"
25
            >
26
                <b-form-input
27
                    id="city_state"
28
                    v-model="city.state"
29
                    placeholder="City state"
30
                ></b-form-input>
31
            </b-form-group>
32
            <b-form-group
33
                id="city_postal_code"
34
                label="ZIP/Postal code"
35
                label-for="postal_code"
36
                label-cols="4" label-cols-lg="2"
37
            >
38
                <b-form-input
39
                    id="postal_code"
40
                    v-model="city.postal_code"
41
                    placeholder="City postal code"
42
                    required
43
                ></b-form-input>
44
            </b-form-group>
45
            <b-form-group
46
                id="city_country"
47
                label="Country:"
48
                label-for="city_country"
49
                label-cols="4" label-cols-lg="2"
50
            >
51
                <b-form-input
52
                    id="city_country"
53
                    v-model="city.country"
54
                    placeholder="City country"
55
                ></b-form-input>
56
            </b-form-group>
57
            <b-button type="submit" variant="primary">Submit</b-button>
58
            <a href="#" @click="$emit('switch-view', 'list')">Cancel</a>
59
        </b-form>
60
    </div>
61
</template>
62
63
<script>
64
65
66
export default {
67
    data() {
68
        return {
69
            city: {
70
                city_id: null,
71
                name: '',
72
                state: '',
73
                postal_code: '',
74
                country: '',
75
            }
76
        }
77
    },
78
   created() {
79
        if( this.city_id ) {
80
81
            const apiUrl = '/api/v1/cities/' + this.city_id;
82
83
            fetch(apiUrl)
84
                .then(res => res.json())
85
                .then(
86
                    (result) => {
87
                        this.city = result
88
                    },
89
                    (error) => {
90
                        this.$emit('set-error', error)
91
                    }
92
                )
93
        }
94
   },
95
    methods:{
96
        onSubmit(){
97
98
            let city = this.city;
99
            let apiUrl = '/api/v1/cities'
100
101
            const myHeaders = new Headers()
102
            myHeaders.append('Content-Type', 'application/json')
103
104
            let method = 'POST'
105
            if ( city.city_id ) {
106
                method = 'PUT'
107
                apiUrl += '/' + city.city_id
108
            }
109
            delete city.city_id
110
111
            const options = {
112
                method: method,
113
                body: JSON.stringify(city),
114
                myHeaders
115
            }
116
117
            fetch(apiUrl, options)
118
                .then(response => {
119
                    if ( response.status == 200 ) {
120
                        this.$emit('city-updated')
121
                    } else if ( response.status == 201 ) {
122
                        this.$emit('city-created')
123
                    } else {
124
                        this.$emit('set-error', response.message || response.statusText)
125
                    }
126
                }, (error) => {
127
                    this.$emit('set-error', error)
128
                })
129
        }
130
    },
131
    emits: ['city-created', 'city-updated', 'set-error', 'switch-view'],
132
    props: {
133
        city_id: Number
134
    },
135
    name: "CitiesFormAdd.vue",
136
}
137
</script>
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/components/CitiesFormConfirmDelete.vue (+107 lines)
Line 0 Link Here
1
<template>
2
    <h2> Delete city</h2>
3
    <div>
4
        <b-form @submit="onSubmit">
5
            <b-form-group
6
                id="city_id"
7
                label="City ID:"
8
                label-for="city_id"
9
                label-cols="4"
10
                label-cols-lg="2"
11
            >
12
                {{city.city_id}}
13
            </b-form-group>
14
            <b-form-group
15
                id="city_name"
16
                label="City name:"
17
                label-for="city_name"
18
                label-cols="4"
19
                label-cols-lg="2"
20
            >
21
                {{city.name}}
22
            </b-form-group>
23
            <b-form-group
24
                id="city_state"
25
                label="State:"
26
                label-for="city_state"
27
                label-cols="4" label-cols-lg="2"
28
            >
29
                {{city.state}}
30
            </b-form-group>
31
            <b-form-group
32
                id="city_postal_code"
33
                label="ZIP/Postal code"
34
                label-for="postal_code"
35
                label-cols="4" label-cols-lg="2"
36
            >
37
                {{city.postal_code}}
38
            </b-form-group>
39
            <b-form-group
40
                id="city_country"
41
                label="Country:"
42
                label-for="city_country"
43
                label-cols="4" label-cols-lg="2"
44
            >
45
                {{city.country}}
46
            </b-form-group>
47
            <b-button type="submit" variant="primary">Submit</b-button>
48
            <a href="#" @click="$emit('switch-view', 'list')">Cancel</a>
49
        </b-form>
50
    </div>
51
</template>
52
53
<script>
54
55
export default {
56
    data() {
57
        return {
58
            city: {},
59
        }
60
    },
61
    created() {
62
        console.log("created" + this.city_id)
63
        const apiUrl = '/api/v1/cities/' + this.city_id;
64
65
        fetch(apiUrl)
66
            .then(res => res.json())
67
            .then(
68
                (result) => {
69
                    this.city = result
70
                },
71
                (error) => {
72
                    this.$emit('set-error', error)
73
                }
74
            )
75
    },
76
    methods:{
77
        onSubmit(){
78
79
            let apiUrl = '/api/v1/cities/' + this.city_id
80
81
            const myHeaders = new Headers()
82
            myHeaders.append('Content-Type', 'application/json')
83
84
            const options = {
85
                method: 'DELETE',
86
                myHeaders
87
            }
88
89
            fetch(apiUrl, options)
90
                .then(response => {
91
                    if ( response.status == 204 ) {
92
                        this.$emit('city-deleted')
93
                    } else {
94
                        this.$emit('set-error', response.message || response.statusText)
95
                    }
96
                }, (error) => {
97
                    this.$emit('set-error', error)
98
                })
99
        }
100
    },
101
    emits: ['city-deleted', 'set-error', 'switch-view'],
102
    props: {
103
        city_id: Number
104
    },
105
    name: "CitiesFormConfirmDelete.vue",
106
}
107
</script>
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/components/CitiesList.vue (+129 lines)
Line 0 Link Here
1
<template>
2
    <div>
3
        <table v-if="cities.length" id="my_table"></table>
4
        <div v-else-if="this.initialized" class="dialog message">There are no cities defined.</div>
5
        <div v-else>Loading...</div>
6
    </div>
7
</template>
8
9
<script>
10
import CitiesButtonEdit from "./CitiesButtonEdit.vue";
11
import CitiesButtonDelete from "./CitiesButtonDelete.vue";
12
import {createVNode, defineComponent, render, resolveComponent} from 'vue'
13
export default {
14
    name: "CitiesList.vue",
15
    created() {
16
        const apiUrl = '/api/v1/cities';
17
18
        fetch(apiUrl)
19
            .then(res => res.json())
20
            .then(
21
                (result) => {
22
                    this.cities = result
23
                    this.initialized = true
24
                },
25
                (error) => {
26
                    this.$emit('set-error', error)
27
                }
28
            )
29
    },
30
    updated() {
31
        let edit_city = this.edit_city;
32
        let delete_city = this.delete_city;
33
        $('#my_table').kohaTable({
34
            "ajax": {
35
                "url": cities_table_url,
36
            },
37
            "order": [[1, "asc"]],
38
            "columnDefs": [{
39
                "targets": [0, 1, 2, 3, 4],
40
                "render": function (data, type, row, meta) {
41
                    if (type == 'display') {
42
                        return escape_str(data);
43
                    }
44
                    return data;
45
                }
46
            }],
47
            "columns": [
48
                {
49
                    "title": __("City ID"),
50
                    "data": "city_id",
51
                    "searchable": true,
52
                    "orderable": true
53
                },
54
                {
55
                    "title": __("City"),
56
                    "data": "name",
57
                    "searchable": true,
58
                    "orderable": true
59
                },
60
                {
61
                    "title": __("State"),
62
                    "data": "state",
63
                    "searchable": true,
64
                    "orderable": true
65
                },
66
                {
67
                    "title": __("ZIP/Postal code"),
68
                    "data": "postal_code",
69
                    "searchable": true,
70
                    "orderable": true
71
                },
72
                {
73
                    "title": __("Country"),
74
                    "data": "country",
75
                    "searchable": true,
76
                    "orderable": true
77
                },
78
                {
79
                    "title": __("Actions"),
80
                    "data": function (row, type, val, meta) {
81
                        return '<div class="actions" data-city_id="' + row.city_id + '"></div>';
82
                    },
83
                    "searchable": false,
84
                    "orderable": false
85
                }
86
            ],
87
            drawCallback: function (settings) {
88
                $.each($(this).find(".actions"), function (index, e) {
89
                    let city_id = $(e).data('city_id')
90
                    let editButton = createVNode(CitiesButtonEdit, {
91
                        onClick: () => {
92
                            edit_city(city_id)
93
                        }
94
                    })
95
                    let deleteButton = createVNode(CitiesButtonDelete, {
96
                        onClick: () => {
97
                            delete_city(city_id)
98
                        }
99
                    })
100
                    let n = createVNode('span', {}, [editButton, deleteButton]);
101
                    render(n, e);
102
                });
103
            }
104
105
        }, table_settings, 1);
106
    },
107
    beforeUnmount() {
108
        $('#my_table')
109
            .DataTable()
110
            .destroy(true);
111
    },
112
    data: function () {
113
        return {
114
            cities: [],
115
            initialized: false,
116
        }
117
    },
118
    methods: {
119
        edit_city: function (city_id) {
120
            this.$emit('set-current-city-id', city_id)
121
            this.$emit('switch-view', 'add-form')
122
        },
123
        delete_city: function (city_id) {
124
            this.$emit('set-current-city-id', city_id)
125
            this.$emit('switch-view', 'confirm-delete-form')
126
        },
127
    }
128
}
129
</script>
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/components/CitiesToolbar.vue (+10 lines)
Line 0 Link Here
1
<template>
2
    <b-button @click="$emit('switch-view', 'add-form')" id="newcity" variant="default"><font-awesome-icon icon="plus" /> New city</b-button>
3
</template>
4
5
<script>
6
export default {
7
    name: "CitiesToolbar.vue",
8
    emits: ['switch-view'],
9
}
10
</script>
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/main-cities.ts (+18 lines)
Line 0 Link Here
1
import {createApp} from 'vue'
2
import BootstrapVue3 from 'bootstrap-vue-3'
3
4
//import 'bootstrap/dist/css/bootstrap.css'
5
import 'bootstrap-vue-3/dist/bootstrap-vue-3.css'
6
7
import {library} from "@fortawesome/fontawesome-svg-core";
8
import {faPlus, faPencil, faTrash} from "@fortawesome/free-solid-svg-icons";
9
import {FontAwesomeIcon} from "@fortawesome/vue-fontawesome";
10
11
library.add(faPlus, faPencil, faTrash)
12
13
import App from './Cities.vue'
14
15
createApp(App)
16
    .component("font-awesome-icon", FontAwesomeIcon)
17
    .use(BootstrapVue3)
18
    .mount('#cities')
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/vue-shims.d.ts (+4 lines)
Line 0 Link Here
1
declare module "*.vue" {
2
    import Vue from "vue";
3
    export default Vue;
4
}
(-)a/package.json (-3 / +35 lines)
Lines 7-13 Link Here
7
    "test": "test"
7
    "test": "test"
8
  },
8
  },
9
  "dependencies": {
9
  "dependencies": {
10
    "bootstrap": "^4.5.2",
10
    "@fortawesome/fontawesome-svg-core": "^6.1.0",
11
    "@fortawesome/free-solid-svg-icons": "^6.0.0",
12
    "@fortawesome/vue-fontawesome": "^3.0.0-5",
13
    "@popperjs/core": "^2.11.2",
14
    "babel-core": "^7.0.0-beta.3",
15
    "bootstrap": "^5.1.3",
16
    "bootstrap-vue": "^2.21.2",
17
    "bootstrap-vue-3": "^0.1.9",
18
    "css-loader": "^6.6.0",
11
    "gulp": "^4.0.2",
19
    "gulp": "^4.0.2",
12
    "gulp-autoprefixer": "^4.0.0",
20
    "gulp-autoprefixer": "^4.0.0",
13
    "gulp-concat-po": "^1.0.0",
21
    "gulp-concat-po": "^1.0.0",
Lines 20-29 Link Here
20
    "js-yaml": "^3.13.1",
28
    "js-yaml": "^3.13.1",
21
    "lodash": "^4.17.12",
29
    "lodash": "^4.17.12",
22
    "merge-stream": "^2.0.0",
30
    "merge-stream": "^2.0.0",
23
    "minimist": "^1.2.5"
31
    "minimist": "^1.2.5",
32
    "style-loader": "^3.3.1",
33
    "vue": "^3.2.31",
34
    "vue-router": "^3.4.3"
24
  },
35
  },
25
  "scripts": {
36
  "scripts": {
26
    "build": "node_modules/.bin/gulp build",
37
    "build": "node_modules/.bin/gulp build",
38
    "build_js": "webpack --mode production",
39
    "watch_js": "webpack --mode development --watch",
27
    "css": "node_modules/.bin/gulp css",
40
    "css": "node_modules/.bin/gulp css",
28
    "watch": "node_modules/.bin/gulp watch"
41
    "watch": "node_modules/.bin/gulp watch"
29
  },
42
  },
Lines 37-41 Link Here
37
    "js-yaml": "^3.13.1"
50
    "js-yaml": "^3.13.1"
38
  },
51
  },
39
  "author": "",
52
  "author": "",
40
  "license": "GPL-3.0"
53
  "license": "GPL-3.0",
54
  "devDependencies": {
55
    "@babel/core": "^7.17.5",
56
    "@babel/preset-env": "^7.16.11",
57
    "@vue/compiler-sfc": "^3.2.31",
58
    "babel-loader": "^8.2.3",
59
    "babelify": "^10.0.0",
60
    "browserify": "^17.0.0",
61
    "clean-webpack-plugin": "^4.0.0",
62
    "gulp-tap": "^1.0.1",
63
    "html-webpack-plugin": "^5.5.0",
64
    "ts-loader": "^9.2.7",
65
    "typescript": "^4.6.2",
66
    "vinyl-source-stream": "^2.0.0",
67
    "vue-loader": "^17.0.0",
68
    "watchify": "^4.0.0",
69
    "webpack": "^5.69.1",
70
    "webpack-cli": "^4.9.2",
71
    "webpack-dev-server": "^4.7.4"
72
  }
41
}
73
}
(-)a/tsconfig.json (+4 lines)
Line 0 Link Here
1
{
2
  "compilerOptions": {
3
  }
4
}
(-)a/webpack.config.js (-1 / +36 lines)
Line 0 Link Here
0
- 
1
const { VueLoaderPlugin } = require("vue-loader");
2
const autoprefixer = require("autoprefixer");
3
const path = require("path");
4
5
module.exports = {
6
  entry: {
7
    main: "./koha-tmpl/intranet-tmpl/prog/js/vue/main-cities.ts",
8
  },
9
  output: {
10
    filename: "[name].js",
11
    path: path.resolve(__dirname, "koha-tmpl/intranet-tmpl/prog/js/vue/dist/"),
12
    chunkFilename: "[name].js",
13
  },
14
  module: {
15
    rules: [
16
      {
17
        test: /\.vue$/,
18
        loader: "vue-loader",
19
      },
20
      {
21
        test: /\.ts$/,
22
        loader: 'ts-loader',
23
        options: {
24
          appendTsSuffixTo: [/\.vue$/]
25
        }
26
      },
27
      {
28
        test: /\.css$/,
29
        use: ['style-loader', 'css-loader']
30
      }
31
    ],
32
  },
33
  plugins: [
34
    new VueLoaderPlugin(),
35
  ],
36
};

Return to bug 30225