Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe

Commits:

13 changed files:

Changes:

  • client/datasource/actions/src/main/i18n/templates/reportHtmlExport_en_GB.ftl
    ... ... @@ -199,112 +199,11 @@
    199 199
             }
    
    200 200
         </style>
    
    201 201
         <script type="application/javascript">
    
    202
    -
    
    203
    -        function searchValue() {
    
    204
    -            return searchOption.checked;
    
    205
    -        }
    
    206
    -
    
    207
    -        function resizableValue() {
    
    208
    -            return resizableOption.checked;
    
    209
    -        }
    
    210
    -
    
    211
    -        function sortValue() {
    
    212
    -            return sortOption.checked;
    
    213
    -        }
    
    214
    -
    
    215
    -        function paginationValue() {
    
    216
    -            return paginationOption.checked ? {limit: paginationSizeOption.value} : false;
    
    217
    -        }
    
    218
    -
    
    219
    -        function toggleSearch(config, source) {
    
    220
    -            let newValue = source.checked;
    
    221
    -            // console.info("Toggle search to: " + newValue);
    
    222
    -            updateGrid(config);
    
    223
    -        }
    
    224
    -
    
    225
    -        function toggleResizable(config, source) {
    
    226
    -            let newValue = source.checked;
    
    227
    -            // console.info("Toggle resizable to: " + newValue);
    
    228
    -            updateGrid(config);
    
    229
    -        }
    
    230
    -
    
    231
    -        function toggleSort(config, source) {
    
    232
    -            let newValue = source.checked;
    
    233
    -            // console.info("Toggle sort to: " + newValue);
    
    234
    -            updateGrid(config);
    
    235
    -        }
    
    236
    -
    
    237
    -        function togglePagination(config, source) {
    
    238
    -            let newValue = source.checked;
    
    239
    -            // console.info("Toggle pagination to: " + newValue);
    
    240
    -            if (newValue) {
    
    241
    -                paginationSizeOption["disabled"] = null;
    
    242
    -            } else {
    
    243
    -                paginationSizeOption.disabled = true;
    
    244
    -            }
    
    245
    -            updateGrid(config);
    
    246
    -        }
    
    247
    -
    
    248
    -        function changePaginationSize(config, source) {
    
    249
    -            let newValue = source.value;
    
    250
    -            // console.info("Change pagination size to: " + newValue);
    
    251
    -            updateGrid(config);
    
    252
    -        }
    
    253
    -
    
    254
    -        function updateGrid(config) {
    
    255
    -            let searchValue1 = searchValue();
    
    256
    -            let sortValue1 = sortValue();
    
    257
    -            let resizableValue1 = resizableValue();
    
    258
    -            // FIXME Need to update config.columns otherwise we will keep previous options (sort, resizable...)
    
    259
    -            let newConfig = {
    
    260
    -                language: config.language,
    
    261
    -                data: config.data,
    
    262
    -                columns: config.columns,
    
    263
    -                search: searchValue1,
    
    264
    -                resizable: resizableValue1,
    
    265
    -                sort: sortValue1,
    
    266
    -                pagination: paginationValue()
    
    267
    -            };
    
    268
    -            gridContainerParent.innerHTML = '<div id="wrapper"></div>';
    
    269
    -            // console.info(newConfig);
    
    270
    -            setTimeout(() => {
    
    271
    -                <#--noinspection JSUnresolvedReference-->
    
    272
    -                grid = new gridjs.Grid(newConfig).render(document.getElementById("wrapper"));
    
    273
    -            }, 50);
    
    274
    -        }
    
    275
    -
    
    276
    -        function deserializeJson(json) {
    
    277
    -            let height = json.height;
    
    278
    -            let width = json.width;
    
    279
    -            let data = json.rows;
    
    280
    -            let result = new Array(height);
    
    281
    -            for (let row = 0; row < height; row++) {
    
    282
    -                let cells = data[row].split('||');
    
    283
    -                let realRow = new Array(width);
    
    284
    -                result[row]=realRow;
    
    285
    -                for (let column = 0; column < width; column++) {
    
    286
    -                    let rowElement = cells[column];
    
    287
    -                    realRow[column] = rowElement ==='$'?null:rowElement;
    
    288
    -                }
    
    289
    -            }
    
    290
    -            return result;
    
    291
    -        }
    
    202
    +        ${.data_model.script}
    
    292 203
     
    
    293 204
             <#list .data_model.columnRendererFunctions as key>
    
    294
    -${key}</#list>
    
    295
    -
    
    296
    -        function createColumns(json) {
    
    297
    -            let result = !!json["columnNames"] ? json["columnNames"] : [];
    
    298
    -            if (result.length === 0) {
    
    299
    -                return result;
    
    300
    -            }
    
    301
    -            let renderers = json["columnRendererDefinitions"];
    
    302
    -            let i = 0;
    
    303
    -            let data = json.data;
    
    304
    -            <#list .data_model.columnRendererInitCode as  value>
    
    305
    -            ${value}</#list>
    
    306
    -            return result;
    
    307
    -        }
    
    205
    +        ${key}
    
    206
    +        </#list>
    
    308 207
         </script>
    
    309 208
     </head>
    
    310 209
     <body>
    
    ... ... @@ -364,62 +263,22 @@ ${key}</#list>
    364 263
     </div>
    
    365 264
     
    
    366 265
     <script type="application/javascript">
    
    367
    -    const json = ${.data_model.json};
    
    368
    -    json.data.data = deserializeJson(json.data);
    
    369
    -
    
    370
    -    const gridContainerParent = document.getElementById("wrapperParent");
    
    371
    -    const searchOption = document.getElementById("search");
    
    372
    -    const resizableOption = document.getElementById("resizable");
    
    373
    -    const paginationOption = document.getElementById("pagination");
    
    374
    -    const paginationSizeOption = document.getElementById("paginationSize");
    
    375
    -    const sortOption = document.getElementById("sort");
    
    376
    -
    
    377
    -    let grid = new gridjs.Grid({
    
    378
    -        search: searchValue(),
    
    379
    -        resizable: resizableValue(),
    
    380
    -        sort: sortValue(),
    
    381
    -        pagination: paginationValue(),
    
    382
    -        <#--language: {-->
    
    383
    -        <#--    'search': {-->
    
    384
    -        <#--        'placeholder': '🔍 Recherche...'-->
    
    385
    -        <#--    },-->
    
    386
    -        <#--    sort: {-->
    
    387
    -        <#--        sortAsc: 'Tri ascendant',-->
    
    388
    -        <#--        sortDesc: 'Tri descendant',-->
    
    389
    -        <#--    },-->
    
    390
    -        <#--    pagination: {-->
    
    391
    -        <#--        previous: 'Précédent',-->
    
    392
    -        <#--        next: 'Suivant',-->
    
    393
    -        <#--        navigate: (page, pages) => `Page ${r"${page}"} sur ${r"${pages}"}`,-->
    
    394
    -        <#--        page: (page) => `Page ${r"${page}"}`,-->
    
    395
    -        <#--        showing: 'Affichage des lignes de',-->
    
    396
    -        <#--        of: 'sur',-->
    
    397
    -        <#--        to: 'à',-->
    
    398
    -        <#--        results: 'lignes.',-->
    
    399
    -        <#--    },-->
    
    400
    -        <#--    loading: 'Chargement...'-->
    
    401
    -        <#--},-->
    
    402
    -        columns: createColumns(json),
    
    403
    -        data: json.data.data
    
    404
    -    });
    
    405
    -    updateGrid(grid.config);
    
    406
    -
    
    407
    -    searchOption.addEventListener("change", function () {
    
    408
    -        toggleSearch(grid.config, this);
    
    409
    -    });
    
    410
    -    resizableOption.addEventListener("change", function () {
    
    411
    -        toggleResizable(grid.config, this);
    
    412
    -    });
    
    413
    -    sortOption.addEventListener("change", function () {
    
    414
    -        toggleSort(grid.config, this);
    
    415
    -    });
    
    416
    -    paginationOption.addEventListener("change", function () {
    
    417
    -        togglePagination(grid.config, this);
    
    418
    -    });
    
    419
    -
    
    420
    -    paginationSizeOption.addEventListener("change", function () {
    
    421
    -        changePaginationSize(grid.config, this);
    
    422
    -    });
    
    266
    +    new GridHandler(
    
    267
    +        document,
    
    268
    +        {},
    
    269
    +        function (json) {
    
    270
    +            let result = !!json["columnNames"] ? json["columnNames"] : [];
    
    271
    +            if (result.length === 0) {
    
    272
    +                return result;
    
    273
    +            }
    
    274
    +            let renderers = json["columnRendererDefinitions"];
    
    275
    +            let i = 0;
    
    276
    +            let data = json.data;
    
    277
    +            <#list .data_model.columnRendererInitCode as  value>
    
    278
    +            ${value}</#list>
    
    279
    +            return result;
    
    280
    +        },
    
    281
    +        ${.data_model.json}).init();
    
    423 282
     </script>
    
    424 283
     </body>
    
    425 284
     </html>

  • client/datasource/actions/src/main/i18n/templates/reportHtmlExport_es_ES.ftl
    ... ... @@ -199,112 +199,11 @@
    199 199
             }
    
    200 200
         </style>
    
    201 201
         <script type="application/javascript">
    
    202
    -
    
    203
    -        function searchValue() {
    
    204
    -            return searchOption.checked;
    
    205
    -        }
    
    206
    -
    
    207
    -        function resizableValue() {
    
    208
    -            return resizableOption.checked;
    
    209
    -        }
    
    210
    -
    
    211
    -        function sortValue() {
    
    212
    -            return sortOption.checked;
    
    213
    -        }
    
    214
    -
    
    215
    -        function paginationValue() {
    
    216
    -            return paginationOption.checked ? {limit: paginationSizeOption.value} : false;
    
    217
    -        }
    
    218
    -
    
    219
    -        function toggleSearch(config, source) {
    
    220
    -            let newValue = source.checked;
    
    221
    -            // console.info("Toggle search to: " + newValue);
    
    222
    -            updateGrid(config);
    
    223
    -        }
    
    224
    -
    
    225
    -        function toggleResizable(config, source) {
    
    226
    -            let newValue = source.checked;
    
    227
    -            // console.info("Toggle resizable to: " + newValue);
    
    228
    -            updateGrid(config);
    
    229
    -        }
    
    230
    -
    
    231
    -        function toggleSort(config, source) {
    
    232
    -            let newValue = source.checked;
    
    233
    -            // console.info("Toggle sort to: " + newValue);
    
    234
    -            updateGrid(config);
    
    235
    -        }
    
    236
    -
    
    237
    -        function togglePagination(config, source) {
    
    238
    -            let newValue = source.checked;
    
    239
    -            // console.info("Toggle pagination to: " + newValue);
    
    240
    -            if (newValue) {
    
    241
    -                paginationSizeOption["disabled"] = null;
    
    242
    -            } else {
    
    243
    -                paginationSizeOption.disabled = true;
    
    244
    -            }
    
    245
    -            updateGrid(config);
    
    246
    -        }
    
    247
    -
    
    248
    -        function changePaginationSize(config, source) {
    
    249
    -            let newValue = source.value;
    
    250
    -            // console.info("Change pagination size to: " + newValue);
    
    251
    -            updateGrid(config);
    
    252
    -        }
    
    253
    -
    
    254
    -        function updateGrid(config) {
    
    255
    -            let searchValue1 = searchValue();
    
    256
    -            let sortValue1 = sortValue();
    
    257
    -            let resizableValue1 = resizableValue();
    
    258
    -            // FIXME Need to update config.columns otherwise we will keep previous options (sort, resizable...)
    
    259
    -            let newConfig = {
    
    260
    -                language: config.language,
    
    261
    -                data: config.data,
    
    262
    -                columns: config.columns,
    
    263
    -                search: searchValue1,
    
    264
    -                resizable: resizableValue1,
    
    265
    -                sort: sortValue1,
    
    266
    -                pagination: paginationValue()
    
    267
    -            };
    
    268
    -            gridContainerParent.innerHTML = '<div id="wrapper"></div>';
    
    269
    -            // console.info(newConfig);
    
    270
    -            setTimeout(() => {
    
    271
    -                <#--noinspection JSUnresolvedReference-->
    
    272
    -                grid = new gridjs.Grid(newConfig).render(document.getElementById("wrapper"));
    
    273
    -            }, 50);
    
    274
    -        }
    
    275
    -
    
    276
    -        function deserializeJson(json) {
    
    277
    -            let height = json.height;
    
    278
    -            let width = json.width;
    
    279
    -            let data = json.rows;
    
    280
    -            let result = new Array(height);
    
    281
    -            for (let row = 0; row < height; row++) {
    
    282
    -                let cells = data[row].split('||');
    
    283
    -                let realRow = new Array(width);
    
    284
    -                result[row]=realRow;
    
    285
    -                for (let column = 0; column < width; column++) {
    
    286
    -                    let rowElement = cells[column];
    
    287
    -                    realRow[column] = rowElement ==='$'?null:rowElement;
    
    288
    -                }
    
    289
    -            }
    
    290
    -            return result;
    
    291
    -        }
    
    202
    +        ${.data_model.script}
    
    292 203
     
    
    293 204
             <#list .data_model.columnRendererFunctions as key>
    
    294
    -${key}</#list>
    
    295
    -
    
    296
    -        function createColumns(json) {
    
    297
    -            let result = !!json["columnNames"] ? json["columnNames"] : [];
    
    298
    -            if (result.length === 0) {
    
    299
    -                return result;
    
    300
    -            }
    
    301
    -            let renderers = json["columnRendererDefinitions"];
    
    302
    -            let i = 0;
    
    303
    -            let data = json.data;
    
    304
    -            <#list .data_model.columnRendererInitCode as  value>
    
    305
    -            ${value}</#list>
    
    306
    -            return result;
    
    307
    -        }
    
    205
    +        ${key}
    
    206
    +        </#list>
    
    308 207
         </script>
    
    309 208
     </head>
    
    310 209
     <body>
    
    ... ... @@ -363,62 +262,22 @@ ${key}</#list>
    363 262
     </div>
    
    364 263
     
    
    365 264
     <script type="application/javascript">
    
    366
    -    const json = ${.data_model.json};
    
    367
    -    json.data.data = deserializeJson(json.data);
    
    368
    -
    
    369
    -    const gridContainerParent = document.getElementById("wrapperParent");
    
    370
    -    const searchOption = document.getElementById("search");
    
    371
    -    const resizableOption = document.getElementById("resizable");
    
    372
    -    const paginationOption = document.getElementById("pagination");
    
    373
    -    const paginationSizeOption = document.getElementById("paginationSize");
    
    374
    -    const sortOption = document.getElementById("sort");
    
    375
    -
    
    376
    -    let grid = new gridjs.Grid({
    
    377
    -        search: searchValue(),
    
    378
    -        resizable: resizableValue(),
    
    379
    -        sort: sortValue(),
    
    380
    -        pagination: paginationValue(),
    
    381
    -        <#--language: {-->
    
    382
    -        <#--    'search': {-->
    
    383
    -        <#--        'placeholder': '🔍 Recherche...'-->
    
    384
    -        <#--    },-->
    
    385
    -        <#--    sort: {-->
    
    386
    -        <#--        sortAsc: 'Tri ascendant',-->
    
    387
    -        <#--        sortDesc: 'Tri descendant',-->
    
    388
    -        <#--    },-->
    
    389
    -        <#--    pagination: {-->
    
    390
    -        <#--        previous: 'Précédent',-->
    
    391
    -        <#--        next: 'Suivant',-->
    
    392
    -        <#--        navigate: (page, pages) => `Page ${r"${page}"} sur ${r"${pages}"}`,-->
    
    393
    -        <#--        page: (page) => `Page ${r"${page}"}`,-->
    
    394
    -        <#--        showing: 'Affichage des lignes de',-->
    
    395
    -        <#--        of: 'sur',-->
    
    396
    -        <#--        to: 'à',-->
    
    397
    -        <#--        results: 'lignes.',-->
    
    398
    -        <#--    },-->
    
    399
    -        <#--    loading: 'Chargement...'-->
    
    400
    -        <#--},-->
    
    401
    -        columns: createColumns(json),
    
    402
    -        data: json.data.data
    
    403
    -    });
    
    404
    -    updateGrid(grid.config);
    
    405
    -
    
    406
    -    searchOption.addEventListener("change", function () {
    
    407
    -        toggleSearch(grid.config, this);
    
    408
    -    });
    
    409
    -    resizableOption.addEventListener("change", function () {
    
    410
    -        toggleResizable(grid.config, this);
    
    411
    -    });
    
    412
    -    sortOption.addEventListener("change", function () {
    
    413
    -        toggleSort(grid.config, this);
    
    414
    -    });
    
    415
    -    paginationOption.addEventListener("change", function () {
    
    416
    -        togglePagination(grid.config, this);
    
    417
    -    });
    
    418
    -
    
    419
    -    paginationSizeOption.addEventListener("change", function () {
    
    420
    -        changePaginationSize(grid.config, this);
    
    421
    -    });
    
    265
    +    new GridHandler(
    
    266
    +        document,
    
    267
    +        {},
    
    268
    +        function (json) {
    
    269
    +            let result = !!json["columnNames"] ? json["columnNames"] : [];
    
    270
    +            if (result.length === 0) {
    
    271
    +                return result;
    
    272
    +            }
    
    273
    +            let renderers = json["columnRendererDefinitions"];
    
    274
    +            let i = 0;
    
    275
    +            let data = json.data;
    
    276
    +            <#list .data_model.columnRendererInitCode as  value>
    
    277
    +            ${value}</#list>
    
    278
    +            return result;
    
    279
    +        },
    
    280
    +        ${.data_model.json}).init();
    
    422 281
     </script>
    
    423 282
     </body>
    
    424 283
     </html>

  • client/datasource/actions/src/main/i18n/templates/reportHtmlExport_fr_FR.ftl
    ... ... @@ -85,22 +85,22 @@
    85 85
                 background-color: rgb(255, 165, 0);
    
    86 86
             }
    
    87 87
     
    
    88
    -<#--        &lt;#&ndash;noinspection CssUnusedSymbol&ndash;&gt;-->
    
    89
    -<#--        td:has(span.cellWarning):before {-->
    
    90
    -<#--            padding-right: 8px;-->
    
    91
    -<#--            content: "\26A0";-->
    
    92
    -<#--        }-->
    
    88
    +        <#--        &lt;#&ndash;noinspection CssUnusedSymbol&ndash;&gt;-->
    
    89
    +        <#--        td:has(span.cellWarning):before {-->
    
    90
    +        <#--            padding-right: 8px;-->
    
    91
    +        <#--            content: "\26A0";-->
    
    92
    +        <#--        }-->
    
    93 93
     
    
    94 94
             <#--noinspection CssUnusedSymbol-->
    
    95 95
             td.cellError {
    
    96 96
                 background-color: rgb(255, 0, 0);
    
    97 97
             }
    
    98 98
     
    
    99
    -<#--        &lt;#&ndash;noinspection CssUnusedSymbol&ndash;&gt;-->
    
    100
    -<#--        td:has(span.cellError):before {-->
    
    101
    -<#--            padding-right: 8px;-->
    
    102
    -<#--            content: "\26D4";-->
    
    103
    -<#--        }-->
    
    99
    +        <#--        &lt;#&ndash;noinspection CssUnusedSymbol&ndash;&gt;-->
    
    100
    +        <#--        td:has(span.cellError):before {-->
    
    101
    +        <#--            padding-right: 8px;-->
    
    102
    +        <#--            content: "\26D4";-->
    
    103
    +        <#--        }-->
    
    104 104
     
    
    105 105
             .widget {
    
    106 106
                 position: relative;
    
    ... ... @@ -200,112 +200,11 @@
    200 200
             }
    
    201 201
         </style>
    
    202 202
         <script type="application/javascript">
    
    203
    -
    
    204
    -        function searchValue() {
    
    205
    -            return searchOption.checked;
    
    206
    -        }
    
    207
    -
    
    208
    -        function resizableValue() {
    
    209
    -            return resizableOption.checked;
    
    210
    -        }
    
    211
    -
    
    212
    -        function sortValue() {
    
    213
    -            return sortOption.checked;
    
    214
    -        }
    
    215
    -
    
    216
    -        function paginationValue() {
    
    217
    -            return paginationOption.checked ? {limit: paginationSizeOption.value} : false;
    
    218
    -        }
    
    219
    -
    
    220
    -        function toggleSearch(config, source) {
    
    221
    -            let newValue = source.checked;
    
    222
    -            // console.info("Toggle search to: " + newValue);
    
    223
    -            updateGrid(config);
    
    224
    -        }
    
    225
    -
    
    226
    -        function toggleResizable(config, source) {
    
    227
    -            let newValue = source.checked;
    
    228
    -            // console.info("Toggle resizable to: " + newValue);
    
    229
    -            updateGrid(config);
    
    230
    -        }
    
    231
    -
    
    232
    -        function toggleSort(config, source) {
    
    233
    -            let newValue = source.checked;
    
    234
    -            // console.info("Toggle sort to: " + newValue);
    
    235
    -            updateGrid(config);
    
    236
    -        }
    
    237
    -
    
    238
    -        function togglePagination(config, source) {
    
    239
    -            let newValue = source.checked;
    
    240
    -            // console.info("Toggle pagination to: " + newValue);
    
    241
    -            if (newValue) {
    
    242
    -                paginationSizeOption["disabled"] = null;
    
    243
    -            } else {
    
    244
    -                paginationSizeOption.disabled = true;
    
    245
    -            }
    
    246
    -            updateGrid(config);
    
    247
    -        }
    
    248
    -
    
    249
    -        function changePaginationSize(config, source) {
    
    250
    -            let newValue = source.value;
    
    251
    -            // console.info("Change pagination size to: " + newValue);
    
    252
    -            updateGrid(config);
    
    253
    -        }
    
    254
    -
    
    255
    -        function updateGrid(config) {
    
    256
    -            let searchValue1 = searchValue();
    
    257
    -            let sortValue1 = sortValue();
    
    258
    -            let resizableValue1 = resizableValue();
    
    259
    -            // FIXME Need to update config.columns otherwise we will keep previous options (sort, resizable...)
    
    260
    -            let newConfig = {
    
    261
    -                language: config.language,
    
    262
    -                data: config.data,
    
    263
    -                columns: config.columns,
    
    264
    -                search: searchValue1,
    
    265
    -                resizable: resizableValue1,
    
    266
    -                sort: sortValue1,
    
    267
    -                pagination: paginationValue()
    
    268
    -            };
    
    269
    -            gridContainerParent.innerHTML = '<div id="wrapper"></div>';
    
    270
    -            // console.info(newConfig);
    
    271
    -            setTimeout(() => {
    
    272
    -                <#--noinspection JSUnresolvedReference-->
    
    273
    -                grid = new gridjs.Grid(newConfig).render(document.getElementById("wrapper"));
    
    274
    -            }, 50);
    
    275
    -        }
    
    276
    -
    
    277
    -        function deserializeJson(json) {
    
    278
    -            let height = json.height;
    
    279
    -            let width = json.width;
    
    280
    -            let data = json.rows;
    
    281
    -            let result = new Array(height);
    
    282
    -            for (let row = 0; row < height; row++) {
    
    283
    -                let cells = data[row].split('||');
    
    284
    -                let realRow = new Array(width);
    
    285
    -                result[row]=realRow;
    
    286
    -                for (let column = 0; column < width; column++) {
    
    287
    -                    let rowElement = cells[column];
    
    288
    -                    realRow[column] = rowElement ==='$'?null:rowElement;
    
    289
    -                }
    
    290
    -            }
    
    291
    -            return result;
    
    292
    -        }
    
    203
    +        ${.data_model.script}
    
    293 204
     
    
    294 205
             <#list .data_model.columnRendererFunctions as key>
    
    295
    -${key}</#list>
    
    296
    -
    
    297
    -        function createColumns(json) {
    
    298
    -            let result = !!json["columnNames"] ? json["columnNames"] : [];
    
    299
    -            if (result.length === 0) {
    
    300
    -                return result;
    
    301
    -            }
    
    302
    -            let renderers = json["columnRendererDefinitions"];
    
    303
    -            let i = 0;
    
    304
    -            let data = json.data;
    
    305
    -            <#list .data_model.columnRendererInitCode as  value>
    
    306
    -            ${value}</#list>
    
    307
    -            return result;
    
    308
    -        }
    
    206
    +        ${key}
    
    207
    +        </#list>
    
    309 208
         </script>
    
    310 209
     </head>
    
    311 210
     <body>
    
    ... ... @@ -364,22 +263,9 @@ ${key}</#list>
    364 263
     </div>
    
    365 264
     
    
    366 265
     <script type="application/javascript">
    
    367
    -    const json = ${.data_model.json};
    
    368
    -    json.data.data = deserializeJson(json.data);
    
    369
    -
    
    370
    -    const gridContainerParent = document.getElementById("wrapperParent");
    
    371
    -    const searchOption = document.getElementById("search");
    
    372
    -    const resizableOption = document.getElementById("resizable");
    
    373
    -    const paginationOption = document.getElementById("pagination");
    
    374
    -    const paginationSizeOption = document.getElementById("paginationSize");
    
    375
    -    const sortOption = document.getElementById("sort");
    
    376
    -
    
    377
    -    let grid = new gridjs.Grid({
    
    378
    -        search: searchValue(),
    
    379
    -        resizable: resizableValue(),
    
    380
    -        sort: sortValue(),
    
    381
    -        pagination: paginationValue(),
    
    382
    -        language: {
    
    266
    +    new GridHandler(
    
    267
    +        document,
    
    268
    +        {
    
    383 269
                 'search': {
    
    384 270
                     'placeholder': '🔍 Recherche...'
    
    385 271
                 },
    
    ... ... @@ -390,8 +276,8 @@ ${key}</#list>
    390 276
                 pagination: {
    
    391 277
                     previous: 'Précédent',
    
    392 278
                     next: 'Suivant',
    
    393
    -                navigate: (page, pages) => `Page ${r"${page}"} sur ${r"${pages}"}`,
    
    394
    -                page: (page) => `Page ${r"${page}"}`,
    
    279
    +                navigate: (page, pages) => `Page ${page} sur ${pages}`,
    
    280
    +                page: (page) => `Page ${page}`,
    
    395 281
                     showing: 'Affichage des lignes de',
    
    396 282
                     of: 'sur',
    
    397 283
                     to: 'à',
    
    ... ... @@ -399,27 +285,19 @@ ${key}</#list>
    399 285
                 },
    
    400 286
                 loading: 'Chargement...'
    
    401 287
             },
    
    402
    -        columns: createColumns(json),
    
    403
    -        data: json.data.data
    
    404
    -    });
    
    405
    -    updateGrid(grid.config);
    
    406
    -
    
    407
    -    searchOption.addEventListener("change", function () {
    
    408
    -        toggleSearch(grid.config, this);
    
    409
    -    });
    
    410
    -    resizableOption.addEventListener("change", function () {
    
    411
    -        toggleResizable(grid.config, this);
    
    412
    -    });
    
    413
    -    sortOption.addEventListener("change", function () {
    
    414
    -        toggleSort(grid.config, this);
    
    415
    -    });
    
    416
    -    paginationOption.addEventListener("change", function () {
    
    417
    -        togglePagination(grid.config, this);
    
    418
    -    });
    
    419
    -
    
    420
    -    paginationSizeOption.addEventListener("change", function () {
    
    421
    -        changePaginationSize(grid.config, this);
    
    422
    -    });
    
    288
    +        function (json) {
    
    289
    +            let result = !!json["columnNames"] ? json["columnNames"] : [];
    
    290
    +            if (result.length === 0) {
    
    291
    +                return result;
    
    292
    +            }
    
    293
    +            let renderers = json["columnRendererDefinitions"];
    
    294
    +            let i = 0;
    
    295
    +            let data = json.data;
    
    296
    +            <#list .data_model.columnRendererInitCode as  value>
    
    297
    +            ${value}</#list>
    
    298
    +            return result;
    
    299
    +        },
    
    300
    +        ${.data_model.json}).init();
    
    423 301
     </script>
    
    424 302
     </body>
    
    425 303
     </html>

  • client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/report/HtmlExportModel.java
    ... ... @@ -24,14 +24,18 @@ package fr.ird.observe.client.datasource.actions.report;
    24 24
     
    
    25 25
     import com.google.gson.Gson;
    
    26 26
     import fr.ird.observe.client.datasource.actions.config.SelectDataModel;
    
    27
    +import fr.ird.observe.dto.ObserveUtil;
    
    27 28
     import fr.ird.observe.report.ColumnRendererConsumers;
    
    28 29
     import fr.ird.observe.report.Report;
    
    29 30
     import fr.ird.observe.report.ReportColumnRenderersParameters;
    
    30 31
     import fr.ird.observe.report.definition.ColumnRendererDefinition;
    
    31 32
     import io.ultreia.java4all.application.template.spi.GenerateTemplate;
    
    33
    +import io.ultreia.java4all.util.SingletonSupplier;
    
    32 34
     import io.ultreia.java4all.util.matrix.DataMatrix;
    
    33 35
     
    
    36
    +import java.net.URL;
    
    34 37
     import java.util.List;
    
    38
    +import java.util.Objects;
    
    35 39
     import java.util.Set;
    
    36 40
     
    
    37 41
     /**
    
    ... ... @@ -44,6 +48,7 @@ import java.util.Set;
    44 48
      */
    
    45 49
     @GenerateTemplate(template = "reportHtmlExport.ftl")
    
    46 50
     public class HtmlExportModel {
    
    51
    +    private static SingletonSupplier<String> SCRIPT_CONTENT;
    
    47 52
         /**
    
    48 53
          * Selected report.
    
    49 54
          */
    
    ... ... @@ -52,7 +57,6 @@ public class HtmlExportModel {
    52 57
          * Selected data model.
    
    53 58
          */
    
    54 59
         private final transient SelectDataModel selectDataModel;
    
    55
    -
    
    56 60
         private final List<String> columnNames;
    
    57 61
         private final List<String> rowNames;
    
    58 62
         private final DataMatrix data;
    
    ... ... @@ -92,6 +96,15 @@ public class HtmlExportModel {
    92 96
             this.json = gson.toJson(this);
    
    93 97
         }
    
    94 98
     
    
    99
    +    public String getScript() {
    
    100
    +        if (SCRIPT_CONTENT == null) {
    
    101
    +            String resourceName = getClass().getSimpleName() + ".js";
    
    102
    +            URL url = Objects.requireNonNull(getClass().getResource(resourceName), "Could not find resource: " + resourceName);
    
    103
    +            SCRIPT_CONTENT = ObserveUtil.loadResourceContentSupplier(url, content -> content.substring(content.indexOf("*/") + 2).trim());
    
    104
    +        }
    
    105
    +        return SCRIPT_CONTENT.get();
    
    106
    +    }
    
    107
    +
    
    95 108
         public String getJson() {
    
    96 109
             return json;
    
    97 110
         }
    

  • client/datasource/actions/src/main/resources/fr/ird/observe/client/datasource/actions/report/HtmlExportModel.js
    1
    +/*-
    
    2
    + * #%L
    
    3
    + * ObServe Client :: DataSource :: Actions
    
    4
    + * %%
    
    5
    + * Copyright (C) 2008 - 2023 IRD, Ultreia.io
    
    6
    + * %%
    
    7
    + * This program is free software: you can redistribute it and/or modify
    
    8
    + * it under the terms of the GNU General Public License as
    
    9
    + * published by the Free Software Foundation, either version 3 of the
    
    10
    + * License, or (at your option) any later version.
    
    11
    + *
    
    12
    + * This program is distributed in the hope that it will be useful,
    
    13
    + * but 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
    
    18
    + * License along with this program.  If not, see
    
    19
    + * <http://www.gnu.org/licenses/gpl-3.0.html>.
    
    20
    + * #L%
    
    21
    + */
    
    22
    +class GridHandler {
    
    23
    +    language;
    
    24
    +    columns;
    
    25
    +    data;
    
    26
    +    searchOption;
    
    27
    +    resizableOption;
    
    28
    +    paginationOption;
    
    29
    +    paginationSizeOption;
    
    30
    +    sortOption;
    
    31
    +    gridContainerParent;
    
    32
    +    search;
    
    33
    +    sort;
    
    34
    +    resizable;
    
    35
    +    pagination;
    
    36
    +
    
    37
    +    constructor(document, language, createColumns, json) {
    
    38
    +        this.gridContainerParent = document.getElementById("wrapperParent");
    
    39
    +        this.searchOption = document.getElementById("search");
    
    40
    +        this.resizableOption = document.getElementById("resizable");
    
    41
    +        this.paginationOption = document.getElementById("pagination");
    
    42
    +        this.paginationSizeOption = document.getElementById("paginationSize");
    
    43
    +        this.sortOption = document.getElementById("sort");
    
    44
    +        this.language = language;
    
    45
    +        json.data.data = this.deserializeJson(json.data);
    
    46
    +        this.columns = createColumns(json);
    
    47
    +        this.data = json.data.data;
    
    48
    +        this.search = this.searchValue();
    
    49
    +        this.resizable = this.resizableValue();
    
    50
    +        this.sort = this.sortValue();
    
    51
    +        this.pagination = this.paginationValue();
    
    52
    +    }
    
    53
    +
    
    54
    +    updateGrid() {
    
    55
    +        this.gridContainerParent.innerHTML = '<div id="wrapper"></div>';
    
    56
    +        setTimeout(() => {
    
    57
    +            // noinspection JSUnresolvedReference
    
    58
    +            new gridjs.Grid({
    
    59
    +                language: this.language,
    
    60
    +                data: this.data,
    
    61
    +                columns: this.deepCopyColumns(this.columns),
    
    62
    +                search: this.search,
    
    63
    +                resizable: this.resizable,
    
    64
    +                sort: this.sort,
    
    65
    +                pagination: this.pagination,
    
    66
    +            }).render(document.getElementById("wrapper"));
    
    67
    +        }, 50);
    
    68
    +    }
    
    69
    +
    
    70
    +    deepCopyColumns(columns) {
    
    71
    +        let result = [];
    
    72
    +        let index = 0;
    
    73
    +        for (const column of columns) {
    
    74
    +            if (column instanceof Object) {
    
    75
    +                let newColumn = {};
    
    76
    +                newColumn['name'] = column['name'];
    
    77
    +                if (!!!column['formatter'] != null) {
    
    78
    +                    newColumn['formatter'] = column['formatter'];
    
    79
    +                }
    
    80
    +                if (column['attributes'] != null) {
    
    81
    +                    newColumn['attributes'] = column['attributes'];
    
    82
    +                }
    
    83
    +                result[index++] = newColumn;
    
    84
    +            } else {
    
    85
    +                result[index++] = column;
    
    86
    +            }
    
    87
    +        }
    
    88
    +        return result;
    
    89
    +    }
    
    90
    +
    
    91
    +    deserializeJson(json) {
    
    92
    +        let height = json.height;
    
    93
    +        let width = json.width;
    
    94
    +        let data = json.rows;
    
    95
    +        let result = new Array(height);
    
    96
    +        for (let row = 0; row < height; row++) {
    
    97
    +            let cells = data[row].split('||');
    
    98
    +            let realRow = new Array(width);
    
    99
    +            result[row] = realRow;
    
    100
    +            for (let column = 0; column < width; column++) {
    
    101
    +                let rowElement = cells[column];
    
    102
    +                realRow[column] = rowElement === '$' ? null : rowElement;
    
    103
    +            }
    
    104
    +        }
    
    105
    +        return result;
    
    106
    +    }
    
    107
    +
    
    108
    +    searchValue() {
    
    109
    +        return this.searchOption.checked;
    
    110
    +    }
    
    111
    +
    
    112
    +    resizableValue() {
    
    113
    +        return this.resizableOption.checked;
    
    114
    +    }
    
    115
    +
    
    116
    +    sortValue() {
    
    117
    +        return this.sortOption.checked;
    
    118
    +    }
    
    119
    +
    
    120
    +    paginationValue() {
    
    121
    +        return this.paginationOption.checked ? {limit: this.paginationSizeOption.value} : false;
    
    122
    +    }
    
    123
    +
    
    124
    +    toggleSearch(source) {
    
    125
    +        this.search = this.searchValue();
    
    126
    +        this.updateGrid();
    
    127
    +    }
    
    128
    +
    
    129
    +    toggleResizable(source) {
    
    130
    +        this.resizable = this.resizableValue();
    
    131
    +        this.updateGrid();
    
    132
    +    }
    
    133
    +
    
    134
    +    toggleSort(source) {
    
    135
    +        this.sort = this.sortValue();
    
    136
    +        this.updateGrid();
    
    137
    +    }
    
    138
    +
    
    139
    +    togglePagination(source) {
    
    140
    +        let newValue = source.checked;
    
    141
    +        if (newValue) {
    
    142
    +            this.paginationSizeOption["disabled"] = null;
    
    143
    +        } else {
    
    144
    +            this.paginationSizeOption.disabled = true;
    
    145
    +        }
    
    146
    +        this.pagination = this.paginationValue();
    
    147
    +        this.updateGrid();
    
    148
    +    }
    
    149
    +
    
    150
    +    changePaginationSize(source) {
    
    151
    +        this.pagination = this.paginationValue();
    
    152
    +        this.updateGrid();
    
    153
    +    }
    
    154
    +
    
    155
    +    init() {
    
    156
    +
    
    157
    +        this.updateGrid();
    
    158
    +        let that = this;
    
    159
    +        this.searchOption.addEventListener("change", function () {
    
    160
    +            that.toggleSearch(this);
    
    161
    +        });
    
    162
    +        this.resizableOption.addEventListener("change", function () {
    
    163
    +            that.toggleResizable(this);
    
    164
    +        });
    
    165
    +        this.sortOption.addEventListener("change", function () {
    
    166
    +            that.toggleSort(this);
    
    167
    +        });
    
    168
    +        this.paginationOption.addEventListener("change", function () {
    
    169
    +            that.togglePagination(this);
    
    170
    +        });
    
    171
    +
    
    172
    +        this.paginationSizeOption.addEventListener("change", function () {
    
    173
    +            that.changePaginationSize(this);
    
    174
    +        });
    
    175
    +    }
    
    176
    +}

  • core/persistence/report/src/main/resources/observe-reports.properties
    ... ... @@ -888,8 +888,8 @@ Left Join t.localMarketSurveySamplingAcquisitionStatus localMarketSurveySampling
    888 888
     Left Join t.advancedSamplingAcquisitionStatus advancedSamplingAcquisitionStatus \
    
    889 889
     Where t.id In :tripId \
    
    890 890
     Order By vessel.code,t.startDate,t.endDate
    
    891
    -report.psLogbookTrip.columnRenderers.1.type=HighlightIfNotI18nReferentialValue
    
    892
    -report.psLogbookTrip.columnRenderers.1.parameters=14,15,16,17,18,19,20,21|fr.ird.referential.ps.common.AcquisitionStatus#1464000000000#001
    
    891
    +report.psLogbookTrip.columnRenderers.1.type=HighlightIfEquals18nReferentialValue
    
    892
    +report.psLogbookTrip.columnRenderers.1.parameters=14,15,16,17,18,19,20,21|fr.ird.referential.ps.common.AcquisitionStatus#1464000000000#999
    
    893 893
     report.psLogbookTrip.columnRenderers.2.type=HighlightIfAbsoluteDeltaIsPositive
    
    894 894
     report.psLogbookTrip.columnRenderers.2.parameters=10|11|0.0001|0.5
    
    895 895
     report.psLogbookTrip.columnRenderers.3.type=HighlightIfAbsoluteDeltaIsPositive
    

  • src/site/markdown/report/embedded-column-renderers.md
    1
    +# Documentation des règles de rendu de colonnes disponibles
    
    2
    +
    
    3
    +Ce document décrit toutes les règles de rendu de colonnes disponibles sur les rapports.
    
    4
    +
    
    5
    +### HighlightIfAbsoluteDeltaIsPositive
    
    6
    +
    
    7
    +Ce rendu permet de vérifier que les valeurs de chaque cellule de deux colonnes sont identiques.
    
    8
    +
    
    9
    +Si deux valeurs ne sont pas égales, on colorise la cellule en orange (avertissement) pour un premier seuil et en rouge 
    
    10
    +(erreur)  selon un second seuil.
    
    11
    +
    
    12
    +Le rendu nécessite quatre paramètres :
    
    13
    +
    
    14
    +* la première colonne
    
    15
    +* la seconde colonne
    
    16
    +* le seuil pour afficher des avertissements
    
    17
    +* le seuil pour afficher des erreurs
    
    18
    +
    
    19
    +Exemple d'utilisation :
    
    20
    +
    
    21
    +```properties
    
    22
    +report.xxx.columnRenderers.1.type=HighlightIfAbsoluteDeltaIsPositive
    
    23
    +report.ccc.columnRenderers.1.parameters=10|11|0.0001|0.5
    
    24
    +```
    
    25
    +
    
    26
    +### HighlightIfNumericalValueIsPositive
    
    27
    +
    
    28
    +Ce rendu permet de vérifier que les valeurs de chaque celleule d'une colonne n'est pas zéro.
    
    29
    +
    
    30
    +Si la valeur n'est pas zéro, on colorise la cellule en orange (avertissement) pour un premier seuil et en rouge
    
    31
    +(erreur)  selon un second seuil.
    
    32
    +
    
    33
    +Le rendu nécessite quatre paramètres :
    
    34
    +
    
    35
    +* la colonne
    
    36
    +* le seuil pour afficher des avertissements
    
    37
    +* le seuil pour afficher des erreurs
    
    38
    + 
    
    39
    +Exemple d'utilisation
    
    40
    +
    
    41
    +```properties
    
    42
    +report.xxx.columnRenderers.1.type=HighlightIfNumericalValueIsPositive
    
    43
    +report.xxx.columnRenderers.1.parameters=19|0.0001|0.5
    
    44
    +```
    
    45
    +
    
    46
    +### HighlightIfEquals18nReferentialValue
    
    47
    +
    
    48
    +Ce rendu permet d'afficher de coloriser en rouge toute cellule des colonnes sélectionnées dont la valeur (de type référentiel i18n) n'est pas celle spécifié (via son identifiant).
    
    49
    +
    
    50
    +Le rendu nécessite deux paramètres :
    
    51
    +
    
    52
    +* une liste de colonnes sépararées par des virgules
    
    53
    +* l'identifiant du référentiel à mettre en valeur
    
    54
    +
    
    55
    +Exemple d'utilisation :
    
    56
    +
    
    57
    +```properties
    
    58
    +report.xxx.columnRenderers.1.type=HighlightIfEquals18nReferentialValue
    
    59
    +report.xxx.columnRenderers.1.parameters=14,15,16,17,18,19,20,21|fr.ird.referential.ps.common.AcquisitionStatus#1464000000000#999
    
    60
    +```

  • src/site/markdown/report/syntax.md
    ... ... @@ -319,6 +319,25 @@ report.xxx.operations.1.comment=Un commentaire optionnel pour documenter l'opér
    319 319
     
    
    320 320
     Les opérations disponibles et leur documentation sont décrites dans le document [suivant](./embedded-operations.html). 
    
    321 321
     
    
    322
    +### Rendu de colonnes
    
    323
    +
    
    324
    +Depuis la version **9.3.0**, il est possible de définir des rendus de colonnes via le fichier de définition, 
    
    325
    +ce rendu sera valable dans le client swing ainsi que dans les rapports html.
    
    326
    +
    
    327
    +Un rendu est défini par deux lignes :
    
    328
    +
    
    329
    +1. Une pour définir le type de rendu
    
    330
    +2. Une pour paramétrer ce rendu
    
    331
    +
    
    332
    +```properties
    
    333
    +report.xxx.columnRenderers.1.type=HighlightIfAbsoluteDeltaIsPositive
    
    334
    +report.ccc.columnRenderers.1.parameters=10|11|0.0001|0.5
    
    335
    +```
    
    336
    + 
    
    337
    +Il est possible d'ajouter plusieurs rendus sur un même rapport.
    
    338
    +
    
    339
    +Les rendus disponibles et leur documentation sont décrits dans le document [suivant](./embedded-column-renderers.html).
    
    340
    +
    
    322 341
     ## Pour aller plus loin
    
    323 342
     
    
    324 343
     Vous pouvez aussi consulter la [documentation des rapports embarqués par l'application](./embedded-reports.html).

  • toolkit/api-report/pom.xml
    ... ... @@ -38,10 +38,6 @@
    38 38
           <groupId>com.google.code.gson</groupId>
    
    39 39
           <artifactId>gson</artifactId>
    
    40 40
         </dependency>
    
    41
    -    <dependency>
    
    42
    -      <groupId>com.google.guava</groupId>
    
    43
    -      <artifactId>guava</artifactId>
    
    44
    -    </dependency>
    
    45 41
         <dependency>
    
    46 42
           <groupId>io.ultreia.java4all</groupId>
    
    47 43
           <artifactId>java-lang</artifactId>
    

  • toolkit/api-report/src/main/java/fr/ird/observe/report/ColumnRendererConsumer.java
    ... ... @@ -22,7 +22,7 @@ package fr.ird.observe.report;
    22 22
      * #L%
    
    23 23
      */
    
    24 24
     
    
    25
    -import com.google.common.io.Resources;
    
    25
    +import fr.ird.observe.dto.ObserveUtil;
    
    26 26
     import fr.ird.observe.report.renderers.HighlightIfAbsoluteDeltaIsPositive;
    
    27 27
     import io.ultreia.java4all.util.SingletonSupplier;
    
    28 28
     import org.jdesktop.swingx.JXTable;
    
    ... ... @@ -31,6 +31,8 @@ import org.jdesktop.swingx.decorator.HighlightPredicate;
    31 31
     
    
    32 32
     import java.awt.Color;
    
    33 33
     import java.io.IOException;
    
    34
    +import java.io.InputStream;
    
    35
    +import java.net.URL;
    
    34 36
     import java.nio.charset.StandardCharsets;
    
    35 37
     import java.util.Objects;
    
    36 38
     
    
    ... ... @@ -53,13 +55,18 @@ public interface ColumnRendererConsumer<P extends ColumnRendererParameters> {
    53 55
         }
    
    54 56
     
    
    55 57
         static SingletonSupplier<String> htmlFunctions(Class<?> type) {
    
    56
    -        return SingletonSupplier.of(() -> {
    
    57
    -            try {
    
    58
    -                return Resources.toString(Objects.requireNonNull(HighlightIfAbsoluteDeltaIsPositive.class.getResource(type.getSimpleName() + ".js")), StandardCharsets.UTF_8);
    
    59
    -            } catch (IOException e) {
    
    60
    -                throw new RuntimeException(e);
    
    61
    -            }
    
    62
    -        });
    
    58
    +        String resourceName = type.getSimpleName() + ".js";
    
    59
    +        URL url = Objects.requireNonNull(HighlightIfAbsoluteDeltaIsPositive.class.getResource(resourceName), "Could not find resource: " + resourceName);
    
    60
    +        return ObserveUtil.loadResourceContentSupplier(url, content -> content.substring(content.indexOf("*/") + 2));
    
    61
    +    }
    
    62
    +
    
    63
    +    static String loadResourceContent(URL url) {
    
    64
    +        try (InputStream in = url.openStream()) {
    
    65
    +            String content = new String(in.readAllBytes(), StandardCharsets.UTF_8);
    
    66
    +            return content.substring(content.indexOf("*/") + 2).trim();
    
    67
    +        } catch (IOException e) {
    
    68
    +            throw new RuntimeException(e);
    
    69
    +        }
    
    63 70
         }
    
    64 71
     
    
    65 72
         /**
    

  • toolkit/api-report/src/main/java/fr/ird/observe/report/renderers/HighlightIfEquals18nReferentialValue.java
    1
    +package fr.ird.observe.report.renderers;
    
    2
    +
    
    3
    +/*-
    
    4
    + * #%L
    
    5
    + * ObServe Toolkit :: API :: Report
    
    6
    + * %%
    
    7
    + * Copyright (C) 2008 - 2023 IRD, Ultreia.io
    
    8
    + * %%
    
    9
    + * This program is free software: you can redistribute it and/or modify
    
    10
    + * it under the terms of the GNU General Public License as
    
    11
    + * published by the Free Software Foundation, either version 3 of the
    
    12
    + * License, or (at your option) any later version.
    
    13
    + *
    
    14
    + * This program is distributed in the hope that it will be useful,
    
    15
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    
    16
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    
    17
    + * GNU General Public License for more details.
    
    18
    + *
    
    19
    + * You should have received a copy of the GNU General Public
    
    20
    + * License along with this program.  If not, see
    
    21
    + * <http://www.gnu.org/licenses/gpl-3.0.html>.
    
    22
    + * #L%
    
    23
    + */
    
    24
    +
    
    25
    +import com.google.auto.service.AutoService;
    
    26
    +import fr.ird.observe.report.ColumnRendererConsumer;
    
    27
    +import fr.ird.observe.report.ColumnRendererParameters;
    
    28
    +import fr.ird.observe.report.ReportRequestExecutor;
    
    29
    +import io.ultreia.java4all.util.SingletonSupplier;
    
    30
    +import org.jdesktop.swingx.JXTable;
    
    31
    +import org.jdesktop.swingx.decorator.ColorHighlighter;
    
    32
    +
    
    33
    +import java.awt.Color;
    
    34
    +import java.util.Map;
    
    35
    +import java.util.Objects;
    
    36
    +import java.util.Set;
    
    37
    +import java.util.TreeSet;
    
    38
    +
    
    39
    +import static fr.ird.observe.report.renderers.HighlightIfEquals18nReferentialValue.Parameters;
    
    40
    +
    
    41
    +/**
    
    42
    + * Created at 02/12/2023.
    
    43
    + *
    
    44
    + * @author Tony Chemit - dev@tchemit.fr
    
    45
    + * @since 9.3.0
    
    46
    + */
    
    47
    +@AutoService(ColumnRendererConsumer.class)
    
    48
    +public class HighlightIfEquals18nReferentialValue implements ColumnRendererConsumer<Parameters> {
    
    49
    +    private final static SingletonSupplier<String> HTML_FUNCTION = ColumnRendererConsumer.htmlFunctions(HighlightIfNotI18nReferentialValue.class);
    
    50
    +
    
    51
    +    @Override
    
    52
    +    public int parametersCount() {
    
    53
    +        return 2;
    
    54
    +    }
    
    55
    +
    
    56
    +    @Override
    
    57
    +    public String parametersSyntax() {
    
    58
    +        return "column1,column2,...,columnN|id";
    
    59
    +    }
    
    60
    +
    
    61
    +    @Override
    
    62
    +    public Parameters parseParameters(String parameters) {
    
    63
    +        String[] split = pareParametersSyntax(parameters);
    
    64
    +        String[] split2 = split[0].trim().split("\\s*,\\s*");
    
    65
    +        Set<Integer> columns = new TreeSet<>();
    
    66
    +        for (String s : split2) {
    
    67
    +            columns.add(Integer.parseInt(s));
    
    68
    +        }
    
    69
    +        String id = split[1];
    
    70
    +        return new Parameters(columns, id);
    
    71
    +    }
    
    72
    +
    
    73
    +    @Override
    
    74
    +    public Parameters createParameters(ReportRequestExecutor requestExecutor, String parameters) {
    
    75
    +        Parameters result = ColumnRendererConsumer.super.createParameters(requestExecutor, parameters);
    
    76
    +        String label = requestExecutor.getReferentialLabel(result.getId());
    
    77
    +        return result.setLabel(label);
    
    78
    +    }
    
    79
    +
    
    80
    +    @Override
    
    81
    +    public Object consumeHtml(Parameters parameters) {
    
    82
    +        return Map.of("name", name(),
    
    83
    +                      "columns", parameters.getColumns(),
    
    84
    +                      "label", parameters.getLabel());
    
    85
    +    }
    
    86
    +
    
    87
    +    @Override
    
    88
    +    public void consumeSwing(Parameters parameters, JXTable table) {
    
    89
    +        table.addHighlighter(new ColorHighlighter((renderer, adapter) -> {
    
    90
    +            Object value = adapter.getValue();
    
    91
    +            int column = adapter.convertColumnIndexToModel(adapter.column);
    
    92
    +            return parameters.getColumns().contains(column) && Objects.equals(value, parameters.getLabel());
    
    93
    +        }, Color.RED, Color.BLACK));
    
    94
    +    }
    
    95
    +
    
    96
    +    @Override
    
    97
    +    public String htmlFunctions() {
    
    98
    +        return HTML_FUNCTION.get();
    
    99
    +    }
    
    100
    +
    
    101
    +    public static final class Parameters implements ColumnRendererParameters {
    
    102
    +        private final Set<Integer> columns;
    
    103
    +        private final String id;
    
    104
    +        private final String label;
    
    105
    +
    
    106
    +        public Parameters(Set<Integer> columns, String id, String label) {
    
    107
    +            this.columns = columns;
    
    108
    +            this.id = id;
    
    109
    +            this.label = label;
    
    110
    +        }
    
    111
    +
    
    112
    +        public Parameters(Set<Integer> columns, String id) {
    
    113
    +            this.columns = columns;
    
    114
    +            this.id = id;
    
    115
    +            this.label = null;
    
    116
    +        }
    
    117
    +
    
    118
    +        @Override
    
    119
    +        public String name() {
    
    120
    +            return HighlightIfEquals18nReferentialValue.class.getSimpleName();
    
    121
    +        }
    
    122
    +
    
    123
    +        public Set<Integer> getColumns() {
    
    124
    +            return columns;
    
    125
    +        }
    
    126
    +
    
    127
    +        public String getId() {
    
    128
    +            return id;
    
    129
    +        }
    
    130
    +
    
    131
    +        public String getLabel() {
    
    132
    +            return label;
    
    133
    +        }
    
    134
    +
    
    135
    +        public Parameters setLabel(String label) {
    
    136
    +            return new Parameters(columns, id, label);
    
    137
    +        }
    
    138
    +    }
    
    139
    +}

  • toolkit/api-report/src/main/resources/fr/ird/observe/report/renderers/HighlightIfEqualsI18nReferentialValue.js
    1
    +/*-
    
    2
    + * #%L
    
    3
    + * ObServe Toolkit :: API :: Report
    
    4
    + * %%
    
    5
    + * Copyright (C) 2008 - 2023 IRD, Ultreia.io
    
    6
    + * %%
    
    7
    + * This program is free software: you can redistribute it and/or modify
    
    8
    + * it under the terms of the GNU General Public License as
    
    9
    + * published by the Free Software Foundation, either version 3 of the
    
    10
    + * License, or (at your option) any later version.
    
    11
    + *
    
    12
    + * This program is distributed in the hope that it will be useful,
    
    13
    + * but 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
    
    18
    + * License along with this program.  If not, see
    
    19
    + * <http://www.gnu.org/licenses/gpl-3.0.html>.
    
    20
    + * #L%
    
    21
    + */
    
    22
    +function HighlightIfEqualsI18nReferentialValue(cell, label) {
    
    23
    +    if (!!!cell) {
    
    24
    +        return;
    
    25
    +    }
    
    26
    +    if (cell === label) {
    
    27
    +        return {
    
    28
    +            'data-cell-content': cell,
    
    29
    +            'class': 'gridjs-td cellError',
    
    30
    +        };
    
    31
    +    }
    
    32
    +}
    
    33
    +
    
    34
    +function initHighlightIfEqualsI18nReferentialValue(renderer, result, json) {
    
    35
    +    let columns = renderer["columns"];
    
    36
    +    let label = renderer["label"];
    
    37
    +    for (let j = 0; j < columns.length; j++) {
    
    38
    +        let column = columns[j];
    
    39
    +        result [column] = {
    
    40
    +            name: result [column],
    
    41
    +            attributes: cell => HighlightIfEqualsI18nReferentialValue(cell, label)
    
    42
    +        };
    
    43
    +    }
    
    44
    +}

  • toolkit/api/src/main/java/fr/ird/observe/dto/ObserveUtil.java
    ... ... @@ -31,15 +31,21 @@ import fr.ird.observe.spi.module.BusinessSubModule;
    31 31
     import io.ultreia.java4all.config.ApplicationConfig;
    
    32 32
     import io.ultreia.java4all.config.ConfigResource;
    
    33 33
     import io.ultreia.java4all.lang.Strings;
    
    34
    +import io.ultreia.java4all.util.SingletonSupplier;
    
    35
    +import org.apache.logging.log4j.LogManager;
    
    36
    +import org.apache.logging.log4j.Logger;
    
    34 37
     import org.apache.logging.log4j.core.config.Configurator;
    
    35 38
     import org.hashids.Hashids;
    
    36 39
     
    
    37 40
     import javax.script.ScriptEngine;
    
    38 41
     import javax.script.ScriptEngineManager;
    
    42
    +import java.io.IOException;
    
    43
    +import java.io.InputStream;
    
    39 44
     import java.lang.reflect.ParameterizedType;
    
    40 45
     import java.lang.reflect.Type;
    
    41 46
     import java.net.MalformedURLException;
    
    42 47
     import java.net.URL;
    
    48
    +import java.nio.charset.StandardCharsets;
    
    43 49
     import java.nio.file.Files;
    
    44 50
     import java.nio.file.Path;
    
    45 51
     import java.text.Collator;
    
    ... ... @@ -75,38 +81,7 @@ public class ObserveUtil {
    75 81
         public static final String PNG_EXTENSION = ".png";
    
    76 82
         public static final String JS_ENGINE_NAME = "rhino";
    
    77 83
         private static final Hashids ID_GENERATOR = new Hashids("ObServeHasSomeSalt", 8, "0123456789#abcdefghijklmnopqrestuvwxyz");
    
    78
    -
    
    79
    -    @SuppressWarnings("rawtypes")
    
    80
    -    private static class ClassComparator<C extends Class<?>> implements Comparator<C> {
    
    81
    -
    
    82
    -        private final Map<Class, String> cache;
    
    83
    -        private final Function<Class, String> function;
    
    84
    -
    
    85
    -        private final Collator collator;
    
    86
    -
    
    87
    -        private ClassComparator(Function<Class, String> function, Locale locale) {
    
    88
    -            this.cache = new HashMap<>();
    
    89
    -            this.function = function;
    
    90
    -            this.collator = Collator.getInstance(locale);
    
    91
    -            this.collator.setStrength(Collator.PRIMARY);
    
    92
    -        }
    
    93
    -
    
    94
    -        @Override
    
    95
    -        public int compare(Class o1, Class o2) {
    
    96
    -            String s1 = getValue(o1);
    
    97
    -            String s2 = getValue(o2);
    
    98
    -            return this.collator.compare(s1, s2);
    
    99
    -        }
    
    100
    -
    
    101
    -        String getValue(Class klass) {
    
    102
    -            return cache.computeIfAbsent(klass, k -> function.apply(klass));
    
    103
    -        }
    
    104
    -
    
    105
    -        public void sort(List<C> list) {
    
    106
    -            list.sort(this);
    
    107
    -            cache.clear();
    
    108
    -        }
    
    109
    -    }
    
    84
    +    private static final Logger log = LogManager.getLogger(ObserveUtil.class);
    
    110 85
     
    
    111 86
         public static String newUUID(Date now) {
    
    112 87
             return ID_GENERATOR.encode(now.getTime());
    
    ... ... @@ -253,15 +228,62 @@ public class ObserveUtil {
    253 228
         }
    
    254 229
     
    
    255 230
         /**
    
    256
    -     *
    
    257 231
          * @param jsonString the json string in compact mode
    
    258 232
          * @return the gson in a pretty mode
    
    259 233
          */
    
    260
    -    public static String toPrettyFormat(String jsonString)
    
    261
    -    {
    
    234
    +    public static String toPrettyFormat(String jsonString) {
    
    262 235
             JsonObject json = JsonParser.parseString(jsonString).getAsJsonObject();
    
    263 236
     
    
    264 237
             Gson gson = new GsonBuilder().setPrettyPrinting().create();
    
    265 238
             return gson.toJson(json);
    
    266 239
         }
    
    240
    +
    
    241
    +    public static SingletonSupplier<String> loadResourceContentSupplier(URL url, Function<String, String> contentTransformer) {
    
    242
    +        return SingletonSupplier.of(() -> {
    
    243
    +            String content = loadResourceContent(url);
    
    244
    +            return contentTransformer == null ? content : contentTransformer.apply(content);
    
    245
    +        });
    
    246
    +    }
    
    247
    +
    
    248
    +    public static String loadResourceContent(URL url) {
    
    249
    +        log.info("Loading resource content: {}", url);
    
    250
    +        try (InputStream in = url.openStream()) {
    
    251
    +            String content = new String(in.readAllBytes(), StandardCharsets.UTF_8);
    
    252
    +            return content.substring(content.indexOf("*/") + 1);
    
    253
    +        } catch (IOException e) {
    
    254
    +            throw new RuntimeException(e);
    
    255
    +        }
    
    256
    +    }
    
    257
    +
    
    258
    +    @SuppressWarnings("rawtypes")
    
    259
    +    private static class ClassComparator<C extends Class<?>> implements Comparator<C> {
    
    260
    +
    
    261
    +        private final Map<Class, String> cache;
    
    262
    +        private final Function<Class, String> function;
    
    263
    +
    
    264
    +        private final Collator collator;
    
    265
    +
    
    266
    +        private ClassComparator(Function<Class, String> function, Locale locale) {
    
    267
    +            this.cache = new HashMap<>();
    
    268
    +            this.function = function;
    
    269
    +            this.collator = Collator.getInstance(locale);
    
    270
    +            this.collator.setStrength(Collator.PRIMARY);
    
    271
    +        }
    
    272
    +
    
    273
    +        @Override
    
    274
    +        public int compare(Class o1, Class o2) {
    
    275
    +            String s1 = getValue(o1);
    
    276
    +            String s2 = getValue(o2);
    
    277
    +            return this.collator.compare(s1, s2);
    
    278
    +        }
    
    279
    +
    
    280
    +        String getValue(Class klass) {
    
    281
    +            return cache.computeIfAbsent(klass, k -> function.apply(klass));
    
    282
    +        }
    
    283
    +
    
    284
    +        public void sort(List<C> list) {
    
    285
    +            list.sort(this);
    
    286
    +            cache.clear();
    
    287
    +        }
    
    288
    +    }
    
    267 289
     }