diff --git a/backend/src/main/resources/db/testdata/V666.18__insert_dummy_dashboards.sql b/backend/src/main/resources/db/testdata/V666.18__insert_dummy_dashboards.sql index 972ca447b..23f795164 100644 --- a/backend/src/main/resources/db/testdata/V666.18__insert_dummy_dashboards.sql +++ b/backend/src/main/resources/db/testdata/V666.18__insert_dummy_dashboards.sql @@ -1,62 +1,105 @@ -- Insert sample data into the dashboard table -INSERT INTO dashboard (id, name, geom, comments, created_at, updated_at) -VALUES - ('e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', 'Dashboard 1', '0106000020E610000001000000010300000001000000210000002C4E13333E8215C0C0D1B96A9B1E48409AF4BD033E5115C008889530691648401EEEE310FD0D15C03409D4F6280F4840C847C4FD10BB14C014AE31FD220948407215D292A95B14C038176075930448409560156471F313C09CF8490EA801484078D57EBF698613C0E413D0127E004840F0780646C31813C068FE593321014840327C37B3B4AE12C078D18E098B0348408F8DAF68514C12C0F057675CA307484049C6665561F511C0983A3421410D484007DD37C33BAD11C074A2DB2C2C144840F70B9A78A67611C0042128801F1C484002C2E771BA5311C040771913CC24484016B7893ECF4511C0442B28FEDB2D4840FE8C0ACD6D4D11C038498CDDF53648407975F6274B6A11C08C58D549C03F48400BCF4B574B9B11C0CCFC4A42E547484087D5254A8CDE11C06CA74968154F4840DE7B455D783112C0E0C2ACEE0A55484033AE37C8DF9012C018AEE1248C5948401163F4F617F912C0A88E098A6D5C48402DEE8A9B1F6613C02CB54859935D4840B54A0315C6D313C014F8D684F25C48407347D2A7D43D14C050D58519915A484018365AF237A014C058134F08865648405DFDA20528F714C0B4813E57F85048409DE6D1974D3F15C0A404DABE1D4A4840AFB76FE2E27515C01CE535BD38424840A30122E9CE9815C0E8AD3F2C963948408E0C801CBAA615C0483B726D8A304840A836FF8D1B9F15C0C844F2416E2748402C4E13333E8215C0C0D1B96A9B1E4840', 'Sample dashboard 1', NOW() - INTERVAL '7 day', NOW() - INTERVAL '3 day'), - ('e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', 'Dashboard 2', '0106000020E61000000100000001030000000100000021000000FF80FC6632D300C0E09A7F86D1474640F6DE0246B18E00C054524FB07A30464061FF58FCD4CAFFBFFCDB4AD21D1A4640C81A95C8BEBBFDBF10ECF5429A054640F2B1D4626104FBBF70EA0192BEF34540E1D994BF75BFF7BF74C60DDF3FE54540EEA0D370250DF4BFA024EA0FB2DA4540CBBEB83CCE11F0BF8070425381D44540BFF33CB138E9E7BF0C9CDC4EEDD2454077B3C4202478DFBF50EE8B4206D645403110CC7F63B2CFBFB481324CACDD454041A012247AF498BFACE04CD890E94540619E1FC70FB2C53F94A28F283AF94540C849F779ACE5D43FCC6645BA080C4640144298A1C833DC3FCC50483B3E214640734A442ABF3DE03FCCF6F4A8053846402BF8720659C9E03FFC6FB7297C4F46400EE01805A96EDF3F38992D30BA664640E7E565C67224DA3F34228B7DDC7C4640805356F719E8D13FF04D3FA60C9146408FC05281912ABC3F00A171CD88A2464076C0AAB22824B8BF246B1B5FAAB04640E093AF674BD2D4BFB0F8CEA2EBBA4640388E0D1CD45FE2BFFC06A710ECC04640111842E4379AEABF3061315D73C246400B598E42AF63F1BF7C01283873BF4640E503C6DA6B4BF5BF788A10BD07B84640663B2F62E6DDF8BF405AB59576AC4640B579A343FAF7FBBFE807A3CE2C9D46405A583D69237BFEBF48CA4B5FBB8A464036CB9239552700C094C5D06BD275464091D5F0EF4BB000C0D85AD54E3B5F4640FF80FC6632D300C0E09A7F86D1474640', 'Sample dashboard 2', NOW(), NOW() + INTERVAL '2 hour'), - ('b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', 'Dashboard 3', '0106000020E61000000100000001030000000100000021000000FA8EC6A47B6801C060BA5D98A957484014F68F37617001C0784128FF885548409ECD737E116E01C0188B5F6762534840889DC736A36101C0E4BEE9FA4A514840D6D29CAB904B01C0F4F98853574F48408FCDA302B32C01C05C383BAF9A4D48402E0DE4E3390601C04C4B5631264C4840421362CE9FD900C0BCB1F337084B4840525D808C9BA800C0047F87CC4B4A48409E3534570F7500C084A07535F84948404FB2F24DF64000C074682BAD104A4840A4C9A5F9500E00C0686ABE41944A48401EBBC63423BEFFBF786967DE7D4B484049D95703126AFFBFE4EA747EC44C48401A20206BA923FFBF7CC89A875B4E48408E6FF0189EEDFEBF804EE84733504840F610CBBB03CAFEBF2C9C409239524840C242389638BAFEBF507E01735A544840AD937008D8BEFEBFE0FE9FF580564840D8F3C897B4D7FEBF2CD66EF3975848403D891EAED903FFBFC06E84E38A5A4840CC9310009541FFBF886FCAA3465C48408D14903D878EFFBF8036A233BA5D484066089468BBE7FFBF18013059D75E484023BA2BF6E12400C044923F2B935F4840D7E1772B6E5800C0940DC67AE65F48402565B934878C00C09C793A18CE5F4840D14D06892CBF00C0D4634EF24A5F4840E6B948E86BEE00C0A486F00C625E4840D02A0081741801C0F4BFEA501C5D484068071CCDA83B01C0540AD235865B4840ADDF3376AE5601C0045C5949AF594840FA8EC6A47B6801C060BA5D98A9574840', 'Sample dashboard 3', NOW() - INTERVAL '1 month', NOW() - INTERVAL '15 day'), - ('c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', 'Dashboard 4', '0106000020E610000001000000010300000001000000210000006A3996E77B6A1340AC32495E5CAF4540345F81FDF771134080D433F4A3AD4540B94378B8007D134050A281E315AC4540ED70F68A298B1340A48FF07FC1AA454066963628E79B1340500891E6B3A94540AFEE9EDE94AE1340885C7E7BF7A84540086500EC7AC213406888748293A845403899648DD5D61340D0096BD68BA8454011B0F184DCEA1340BC1621C3E0A845405A28E1CBCAFD13408CE529028FA945402252D524E60E14404CAC97DB8FAA454016341044861D14408882F268D9AB45402CA922471B2914401885C6F75EAD45400333733C33311440CC92D28711AF45408BA436847E351440E8C9CC5FE0B045405999C6DFD235144018E2D6B2B9B24540734C3B112D321440188622508BB44540A92650FBB02A14405C48F15543B6454024425940A81F144018960DE1D0B74540F014DB6D7F11144054CE0FB224B9454077EF9AD0C1001440186D37C231BA45402E97321A14EE134040094DC2EDBA4540D520D10C2EDA13400862DE7E51BB4540A5EC6C6BD3C51340F8BB282659BB4540CBD5DF73CCB11340ACDF256D04BB4540835DF02CDE9E134074A7639256BA4540BB33FCD3C28D134024C18B3E56B94540C751C1B4227F1340FCC4BF430DB84540B1DCAEB18D73134088AE233E88B64540DA525EBC756B1340C4B51419D6B4454052E19A742A67134008FE927D07B3454084EC0A19D6661340CC0A482F2EB145406A3996E77B6A1340AC32495E5CAF4540', 'Sample dashboard 4', NOW() - INTERVAL '15 day', NOW()); +INSERT INTO dashboard (id, name, geom, comments, created_at, updated_at, sea_front) +VALUES ('e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', 'Dashboard 1', + '0106000020E610000001000000010300000001000000210000002C4E13333E8215C0C0D1B96A9B1E48409AF4BD033E5115C008889530691648401EEEE310FD0D15C03409D4F6280F4840C847C4FD10BB14C014AE31FD220948407215D292A95B14C038176075930448409560156471F313C09CF8490EA801484078D57EBF698613C0E413D0127E004840F0780646C31813C068FE593321014840327C37B3B4AE12C078D18E098B0348408F8DAF68514C12C0F057675CA307484049C6665561F511C0983A3421410D484007DD37C33BAD11C074A2DB2C2C144840F70B9A78A67611C0042128801F1C484002C2E771BA5311C040771913CC24484016B7893ECF4511C0442B28FEDB2D4840FE8C0ACD6D4D11C038498CDDF53648407975F6274B6A11C08C58D549C03F48400BCF4B574B9B11C0CCFC4A42E547484087D5254A8CDE11C06CA74968154F4840DE7B455D783112C0E0C2ACEE0A55484033AE37C8DF9012C018AEE1248C5948401163F4F617F912C0A88E098A6D5C48402DEE8A9B1F6613C02CB54859935D4840B54A0315C6D313C014F8D684F25C48407347D2A7D43D14C050D58519915A484018365AF237A014C058134F08865648405DFDA20528F714C0B4813E57F85048409DE6D1974D3F15C0A404DABE1D4A4840AFB76FE2E27515C01CE535BD38424840A30122E9CE9815C0E8AD3F2C963948408E0C801CBAA615C0483B726D8A304840A836FF8D1B9F15C0C844F2416E2748402C4E13333E8215C0C0D1B96A9B1E4840', + 'Sample dashboard 1', NOW() - INTERVAL '7 day', NOW() - INTERVAL '3 day', 'NAMO'), + ('e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', 'Dashboard 2', + '0106000020E61000000100000001030000000100000021000000FF80FC6632D300C0E09A7F86D1474640F6DE0246B18E00C054524FB07A30464061FF58FCD4CAFFBFFCDB4AD21D1A4640C81A95C8BEBBFDBF10ECF5429A054640F2B1D4626104FBBF70EA0192BEF34540E1D994BF75BFF7BF74C60DDF3FE54540EEA0D370250DF4BFA024EA0FB2DA4540CBBEB83CCE11F0BF8070425381D44540BFF33CB138E9E7BF0C9CDC4EEDD2454077B3C4202478DFBF50EE8B4206D645403110CC7F63B2CFBFB481324CACDD454041A012247AF498BFACE04CD890E94540619E1FC70FB2C53F94A28F283AF94540C849F779ACE5D43FCC6645BA080C4640144298A1C833DC3FCC50483B3E214640734A442ABF3DE03FCCF6F4A8053846402BF8720659C9E03FFC6FB7297C4F46400EE01805A96EDF3F38992D30BA664640E7E565C67224DA3F34228B7DDC7C4640805356F719E8D13FF04D3FA60C9146408FC05281912ABC3F00A171CD88A2464076C0AAB22824B8BF246B1B5FAAB04640E093AF674BD2D4BFB0F8CEA2EBBA4640388E0D1CD45FE2BFFC06A710ECC04640111842E4379AEABF3061315D73C246400B598E42AF63F1BF7C01283873BF4640E503C6DA6B4BF5BF788A10BD07B84640663B2F62E6DDF8BF405AB59576AC4640B579A343FAF7FBBFE807A3CE2C9D46405A583D69237BFEBF48CA4B5FBB8A464036CB9239552700C094C5D06BD275464091D5F0EF4BB000C0D85AD54E3B5F4640FF80FC6632D300C0E09A7F86D1474640', + 'Sample dashboard 2', NOW() - INTERVAL '1 day', NOW() - INTERVAL '1 hour', 'SA'), + ('b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', 'Dashboard 3', + '0106000020E61000000100000001030000000100000021000000FA8EC6A47B6801C060BA5D98A957484014F68F37617001C0784128FF885548409ECD737E116E01C0188B5F6762534840889DC736A36101C0E4BEE9FA4A514840D6D29CAB904B01C0F4F98853574F48408FCDA302B32C01C05C383BAF9A4D48402E0DE4E3390601C04C4B5631264C4840421362CE9FD900C0BCB1F337084B4840525D808C9BA800C0047F87CC4B4A48409E3534570F7500C084A07535F84948404FB2F24DF64000C074682BAD104A4840A4C9A5F9500E00C0686ABE41944A48401EBBC63423BEFFBF786967DE7D4B484049D95703126AFFBFE4EA747EC44C48401A20206BA923FFBF7CC89A875B4E48408E6FF0189EEDFEBF804EE84733504840F610CBBB03CAFEBF2C9C409239524840C242389638BAFEBF507E01735A544840AD937008D8BEFEBFE0FE9FF580564840D8F3C897B4D7FEBF2CD66EF3975848403D891EAED903FFBFC06E84E38A5A4840CC9310009541FFBF886FCAA3465C48408D14903D878EFFBF8036A233BA5D484066089468BBE7FFBF18013059D75E484023BA2BF6E12400C044923F2B935F4840D7E1772B6E5800C0940DC67AE65F48402565B934878C00C09C793A18CE5F4840D14D06892CBF00C0D4634EF24A5F4840E6B948E86BEE00C0A486F00C625E4840D02A0081741801C0F4BFEA501C5D484068071CCDA83B01C0540AD235865B4840ADDF3376AE5601C0045C5949AF594840FA8EC6A47B6801C060BA5D98A9574840', + 'Sample dashboard 3', NOW() - INTERVAL '1 month', NOW() - INTERVAL '15 day', 'NAMO'), + ('c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', 'Dashboard 4', + '0106000020E610000001000000010300000001000000210000006A3996E77B6A1340AC32495E5CAF4540345F81FDF771134080D433F4A3AD4540B94378B8007D134050A281E315AC4540ED70F68A298B1340A48FF07FC1AA454066963628E79B1340500891E6B3A94540AFEE9EDE94AE1340885C7E7BF7A84540086500EC7AC213406888748293A845403899648DD5D61340D0096BD68BA8454011B0F184DCEA1340BC1621C3E0A845405A28E1CBCAFD13408CE529028FA945402252D524E60E14404CAC97DB8FAA454016341044861D14408882F268D9AB45402CA922471B2914401885C6F75EAD45400333733C33311440CC92D28711AF45408BA436847E351440E8C9CC5FE0B045405999C6DFD235144018E2D6B2B9B24540734C3B112D321440188622508BB44540A92650FBB02A14405C48F15543B6454024425940A81F144018960DE1D0B74540F014DB6D7F11144054CE0FB224B9454077EF9AD0C1001440186D37C231BA45402E97321A14EE134040094DC2EDBA4540D520D10C2EDA13400862DE7E51BB4540A5EC6C6BD3C51340F8BB282659BB4540CBD5DF73CCB11340ACDF256D04BB4540835DF02CDE9E134074A7639256BA4540BB33FCD3C28D134024C18B3E56B94540C751C1B4227F1340FCC4BF430DB84540B1DCAEB18D73134088AE233E88B64540DA525EBC756B1340C4B51419D6B4454052E19A742A67134008FE927D07B3454084EC0A19D6661340CC0A482F2EB145406A3996E77B6A1340AC32495E5CAF4540', + 'Sample dashboard 4', NOW() - INTERVAL '15 day', NOW(), 'MED'); -- Insert sample data into the dashboard_datas table -- Dashboard 1 with no Amp -INSERT INTO dashboard_datas (id, dashboard_id, reportings_id, amp_cacem_id, regulations_cacem_id, vigilance_area_id, control_unit_id, insee_code) -VALUES - ('e1e99b92-1e61-4f9f-9cbf-8cfae2395d41','e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', 1, null, null, null, null, null), -- reportingId -- - ('43f2ec9c-98f0-4841-bbee-88c08692ca1e','e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', 2, null, null, null, null, null), -- reportingId -- - ('f8f876d6-af23-415c-8051-a485564b45bc','e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, 625, null, null, null), -- regulatoryAreaId -- - ('cd136bbe-db51-46c0-a73b-7b7e3d9e9ee7','e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, 134, null, null, null), -- regulatoryAreaId -- - ('a8f48cc8-47f2-450e-bb45-5919c9b45e7d','e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, 300, null, null, null), -- regulatoryAreaId -- - ('49ba7340-377c-48c8-a9ef-3d617f529290','e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, 625, null, null, null), -- regulatoryAreaId -- - ('de391685-2262-4080-be14-b97b1e713360','e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, null, 7, null, null), -- vigilanceAreaId -- - ('a00f61f9-fd25-4ffc-8ab4-ab48d89656f8','e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, null, null, 10002, null), -- controlUnitId -- - ('45ccdb8a-6011-4425-824c-d2016719e158','e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, null, null, null, '56'); -- inseeCode -- +INSERT INTO dashboard_datas (id, dashboard_id, reportings_id, amp_cacem_id, regulations_cacem_id, vigilance_area_id, + control_unit_id, insee_code) +VALUES ('e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', 'e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', 1, null, null, null, null, + null), -- reportingId -- + ('43f2ec9c-98f0-4841-bbee-88c08692ca1e', 'e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', 2, null, null, null, null, + null), -- reportingId -- + ('f8f876d6-af23-415c-8051-a485564b45bc', 'e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, 625, null, null, + null), -- regulatoryAreaId -- + ('cd136bbe-db51-46c0-a73b-7b7e3d9e9ee7', 'e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, 134, null, null, + null), -- regulatoryAreaId -- + ('a8f48cc8-47f2-450e-bb45-5919c9b45e7d', 'e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, 300, null, null, + null), -- regulatoryAreaId -- + ('49ba7340-377c-48c8-a9ef-3d617f529290', 'e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, 625, null, null, + null), -- regulatoryAreaId -- + ('de391685-2262-4080-be14-b97b1e713360', 'e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, null, 7, null, + null), -- vigilanceAreaId -- + ('a00f61f9-fd25-4ffc-8ab4-ab48d89656f8', 'e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, null, null, 10002, + null), -- controlUnitId -- + ('45ccdb8a-6011-4425-824c-d2016719e158', 'e1e99b92-1e61-4f9f-9cbf-8cfae2395d41', null, null, null, null, null, + '56'); +-- inseeCode -- -- Dashboard 2 with all -INSERT INTO dashboard_datas (id, dashboard_id, reportings_id, amp_cacem_id, regulations_cacem_id, vigilance_area_id, control_unit_id, insee_code) -VALUES - ('aade45ca-1451-4001-b21f-afbdcce19e08','e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', 6, null, null, null, null, null), -- reportingId -- - ('4c38005d-fcce-4cf7-a845-26beaee6da70','e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', null, 7, null, null, null, null), -- ampId -- - ('8f17722d-7102-4223-b5a5-f70830205dc8','e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', null, null, 134, null, null, null), -- regulatoryAreaId -- - ('27df62c9-eb79-46c1-b4bc-752d10d24aa6','e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', null, null, null, 9, null, null), -- vigilanceAreaId -- - ('89a821df-2cf6-4976-978c-c9c294c60cf6','e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', null, null, null, null, 10000, null), -- controlUnitId -- - ('12fdc187-70ec-49a8-b3ed-ab2f47b524a2','e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', null, null, null, null, null, '33'); -- inseeCode -- +INSERT INTO dashboard_datas (id, dashboard_id, reportings_id, amp_cacem_id, regulations_cacem_id, vigilance_area_id, + control_unit_id, insee_code) +VALUES ('aade45ca-1451-4001-b21f-afbdcce19e08', 'e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', 6, null, null, null, null, + null), -- reportingId -- + ('4c38005d-fcce-4cf7-a845-26beaee6da70', 'e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', null, 7, null, null, null, + null), -- ampId -- + ('8f17722d-7102-4223-b5a5-f70830205dc8', 'e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', null, null, 134, null, null, + null), -- regulatoryAreaId -- + ('27df62c9-eb79-46c1-b4bc-752d10d24aa6', 'e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', null, null, null, 9, null, + null), -- vigilanceAreaId -- + ('89a821df-2cf6-4976-978c-c9c294c60cf6', 'e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', null, null, null, null, 10000, + null), -- controlUnitId -- + ('12fdc187-70ec-49a8-b3ed-ab2f47b524a2', 'e2a7d0ae-55ff-4fd9-8a6d-88b92d2b1a42', null, null, null, null, null, + '33'); +-- inseeCode -- -- Dashboard 3 with no ReagulatoryAreas -INSERT INTO dashboard_datas (id, dashboard_id, reportings_id, amp_cacem_id, regulations_cacem_id, vigilance_area_id, control_unit_id, insee_code) -VALUES - ('200b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4d5e','b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', 10, null, null, null, null, ''), -- reportingId -- - ('300c3d4e-5f6a-7b8c-9d0e-1f2a3b4d5e6f','b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', 6, null, null, null, null, ''), -- reportingId -- - ('3a6e9337-2efd-4b6f-96b7-9c62080174a4','b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, 5, null, null, null, ''), -- ampId -- - ('f085e7d6-6d08-4fe5-9ffe-e9fb458957a5','b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, 6, null, null, null, ''), -- ampId -- - ('17ccb0ff-c3e5-4494-a5c5-4baa57f99d1e','b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, 7, null, null, null, ''), -- ampId -- - ('02d7ea96-a426-45c5-8b7a-cc7399119c67','b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, 8, null, null, null, ''), -- ampId -- - ('e1500e25-9935-43dc-92c2-41926545f047','b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, null, null, 4, null, ''), -- vigilanceAreaId -- - ('5c625c0a-cec3-4981-9245-693762816e0c','b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, null, null, 9, null, ''), -- vigilanceAreaId -- - ('c3060bc9-0051-4e49-964a-2991ca4a167f','b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, null, null, null, 10023, ''), -- controlUnitId -- - ('13bb9341-89ed-4a6d-a4b3-7e4284a3d850','b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, null, null, null, null, '29'); -- inseeCode -- +INSERT INTO dashboard_datas (id, dashboard_id, reportings_id, amp_cacem_id, regulations_cacem_id, vigilance_area_id, + control_unit_id, insee_code) +VALUES ('200b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4d5e', 'b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', 10, null, null, null, null, + ''), -- reportingId -- + ('300c3d4e-5f6a-7b8c-9d0e-1f2a3b4d5e6f', 'b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', 6, null, null, null, null, + ''), -- reportingId -- + ('3a6e9337-2efd-4b6f-96b7-9c62080174a4', 'b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, 5, null, null, null, + ''), -- ampId -- + ('f085e7d6-6d08-4fe5-9ffe-e9fb458957a5', 'b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, 6, null, null, null, + ''), -- ampId -- + ('17ccb0ff-c3e5-4494-a5c5-4baa57f99d1e', 'b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, 7, null, null, null, + ''), -- ampId -- + ('02d7ea96-a426-45c5-8b7a-cc7399119c67', 'b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, 8, null, null, null, + ''), -- ampId -- + ('e1500e25-9935-43dc-92c2-41926545f047', 'b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, null, null, 4, null, + ''), -- vigilanceAreaId -- + ('5c625c0a-cec3-4981-9245-693762816e0c', 'b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, null, null, 9, null, + ''), -- vigilanceAreaId -- + ('c3060bc9-0051-4e49-964a-2991ca4a167f', 'b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, null, null, null, 10023, + ''), -- controlUnitId -- + ('13bb9341-89ed-4a6d-a4b3-7e4284a3d850', 'b28b8b22-93d4-45d9-8d5d-9ddcbf3e5e53', null, null, null, null, null, + '29'); +-- inseeCode -- -- Dashboard 3 with no Reportings -INSERT INTO dashboard_datas (id, dashboard_id, reportings_id, amp_cacem_id, regulations_cacem_id, vigilance_area_id, control_unit_id, insee_code) -VALUES - ('396b4ff4-4285-47a8-bd6a-1cac1e1e7871','c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, 13, null, null, null, ''), -- ampId -- - ('837da234-52dd-4212-bfdb-50cae6633b5f','c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, 20, null, null, null, ''), -- ampId -- - ('5f0a65fe-eeb6-4558-8664-19690e9c65a1','c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, null, 329, null, null, null), -- regulatoryAreaId -- - ('56fedbc2-e523-44ef-bc87-03d336a25137','c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, null, 359, null, null, null), -- regulatoryAreaId -- - ('bbe52d94-0fe8-4853-ba6a-bffb07dfc26d','c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, null, null, 4, null, ''), -- vigilanceAreaId -- - ('ce71d064-8b41-4277-afed-bafb3c31024e','c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, null, null, 5, null, ''), -- vigilanceAreaId -- - ('c846cd07-fabd-44f8-9fbe-f0452cd68a08','c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, null, null, null, 10016, ''), -- controlUnitId -- - ('01bb9cd2-00d4-4b4f-8ea5-55f94ce7fb04','c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, null, null, null, null, '34'); -- inseeCode -- +INSERT INTO dashboard_datas (id, dashboard_id, reportings_id, amp_cacem_id, regulations_cacem_id, vigilance_area_id, + control_unit_id, insee_code) +VALUES ('396b4ff4-4285-47a8-bd6a-1cac1e1e7871', 'c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, 13, null, null, null, + ''), -- ampId -- + ('837da234-52dd-4212-bfdb-50cae6633b5f', 'c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, 20, null, null, null, + ''), -- ampId -- + ('5f0a65fe-eeb6-4558-8664-19690e9c65a1', 'c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, null, 329, null, null, + null), -- regulatoryAreaId -- + ('56fedbc2-e523-44ef-bc87-03d336a25137', 'c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, null, 359, null, null, + null), -- regulatoryAreaId -- + ('bbe52d94-0fe8-4853-ba6a-bffb07dfc26d', 'c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, null, null, 4, null, + ''), -- vigilanceAreaId -- + ('ce71d064-8b41-4277-afed-bafb3c31024e', 'c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, null, null, 5, null, + ''), -- vigilanceAreaId -- + ('c846cd07-fabd-44f8-9fbe-f0452cd68a08', 'c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, null, null, null, 10016, + ''), -- controlUnitId -- + ('01bb9cd2-00d4-4b4f-8ea5-55f94ce7fb04', 'c8c92b8d-832f-4ba9-96e1-dca3fb6c6f64', null, null, null, null, null, + '34'); -- inseeCode -- diff --git a/frontend/cypress/e2e/side_window/dashboard_list/filters.spec.ts b/frontend/cypress/e2e/side_window/dashboard_list/filters.spec.ts new file mode 100644 index 000000000..0bc3d86a9 --- /dev/null +++ b/frontend/cypress/e2e/side_window/dashboard_list/filters.spec.ts @@ -0,0 +1,105 @@ +import { customDayjs } from '@mtes-mct/monitor-ui' + +import { getUtcDateInMultipleFormats } from '../../utils/getUtcDateInMultipleFormats' +import { visitSideWindow } from '../../utils/visitSideWindow' + +context('Side Window > Dashboard List > Filter Bar', () => { + beforeEach(() => { + cy.viewport(1280, 1024) + visitSideWindow() + cy.clickButton('Tableaux de bord') + }) + + it('Should filter dashboard for today', () => { + cy.fill('Date de mise à jour', 'Aujourd’hui') + + cy.get('.Table-SimpleTable tr').should('have.length.to.be.greaterThan', 0) + + cy.clickButton('Réinitialiser les filtres') + }) + + it('Should filter dashboard for the last week', () => { + cy.fill('Date de mise à jour', 'Une semaine') + + cy.get('.Table-SimpleTable tr').should('have.length.to.be.greaterThan', 0) + + cy.clickButton('Réinitialiser les filtres') + }) + + it('Should filter dashboard for the last month', () => { + cy.fill('Date de mise à jour', 'Un mois') + + cy.get('.Table-SimpleTable tr').should('have.length.to.be.greaterThan', 0) + }) + + it('Should filter dashboard for the current year', () => { + cy.fill('Date de mise à jour', 'Année en cours') + + cy.get('.Table-SimpleTable tr').should('have.length.to.be.greaterThan', 0) + + cy.clickButton('Réinitialiser les filtres') + }) + + it('Should filter dashboards by specific period', () => { + cy.fill('Date de mise à jour', 'Période spécifique') + + const expectedStartDate = getUtcDateInMultipleFormats('2024-01-01T00:00:00.000Z') + const expectedEndDate = getUtcDateInMultipleFormats(customDayjs().toISOString()) + + cy.fill('Période spécifique de la date de mise à jour', [ + expectedStartDate.asDatePickerDate, + expectedEndDate.asDatePickerDate + ]) + + cy.get('.Table-SimpleTable tr').should('have.length.to.be.greaterThan', 0) + + cy.clickButton('Réinitialiser les filtres') + }) + + it('Should filter dashboard by sea front', () => { + cy.wait(200) + cy.fill('Façade', ['NAMO']) + + cy.get('.Table-SimpleTable tr').should('have.length.to.be.greaterThan', 0) + cy.get('.Table-SimpleTable tr').each((row, index) => { + if (index === 0) { + return + } + + cy.wrap(row).should('contain', 'NAMO') + }) + + cy.clickButton('Réinitialiser les filtres') + }) + + it('Should filter dashboard by regulatory themes', () => { + cy.wait(200) + cy.fill('Thématique réglementaire', ['RNN']) + + cy.get('.Table-SimpleTable tr').should('have.length.to.be.greaterThan', 0) + cy.get('.Table-SimpleTable tr').each((row, index) => { + if (index === 0) { + return + } + + cy.wrap(row).should('contain', 'RNN Iroise') + }) + + cy.clickButton('Réinitialiser les filtres') + }) + + it('Should filter dashboards by units', () => { + cy.fill('Unité', ['DML']) + + cy.get('.Table-SimpleTable tr').should('have.length.to.be.greaterThan', 0) + cy.get('.Table-SimpleTable tr').each((row, index) => { + if (index === 0) { + return + } + + cy.wrap(row).should('contain', 'DML 2A (DDTM)') + }) + + cy.clickButton('Réinitialiser les filtres') + }) +}) diff --git a/frontend/src/features/Dashboard/components/DashboardForm/Columns/FirstColumn.tsx b/frontend/src/features/Dashboard/components/DashboardForm/Columns/FirstColumn.tsx index 0213a67f2..5bcf4f802 100644 --- a/frontend/src/features/Dashboard/components/DashboardForm/Columns/FirstColumn.tsx +++ b/frontend/src/features/Dashboard/components/DashboardForm/Columns/FirstColumn.tsx @@ -1,3 +1,4 @@ +import { useObserverAccordion } from '@features/Dashboard/hooks/useObserverAccordion' import { getFilteredAmps, getFilteredRegulatoryAreas, @@ -14,7 +15,6 @@ import { RegulatoryAreas } from '../RegulatoryAreas' import { VigilanceAreas } from '../VigilanceAreas' import { BaseColumn } from './style' import { type ColumnProps } from './utils' -import { useObserverAccordion } from '../useObserverAccordion' import type { DashboardFilters } from '../slice' diff --git a/frontend/src/features/Dashboard/components/DashboardForm/Columns/SecondColumn.tsx b/frontend/src/features/Dashboard/components/DashboardForm/Columns/SecondColumn.tsx index d3dd92b46..2838f598c 100644 --- a/frontend/src/features/Dashboard/components/DashboardForm/Columns/SecondColumn.tsx +++ b/frontend/src/features/Dashboard/components/DashboardForm/Columns/SecondColumn.tsx @@ -1,3 +1,4 @@ +import { useObserverAccordion } from '@features/Dashboard/hooks/useObserverAccordion' import { getFilteredReportings, type DashboardType } from '@features/Dashboard/slice' import { Dashboard } from '@features/Dashboard/types' import { useAppSelector } from '@hooks/useAppSelector' @@ -9,7 +10,6 @@ import { getReportingFilters } from '../slice' import { TerritorialPressure } from '../TerritorialPressure' import { BaseColumn } from './style' import { type ColumnProps } from './utils' -import { useObserverAccordion } from '../useObserverAccordion' type SecondColumnProps = { dashboardForm: [string, DashboardType] diff --git a/frontend/src/features/Dashboard/components/DashboardForm/Columns/ThirdColumn.tsx b/frontend/src/features/Dashboard/components/DashboardForm/Columns/ThirdColumn.tsx index a80449de5..0708ee60c 100644 --- a/frontend/src/features/Dashboard/components/DashboardForm/Columns/ThirdColumn.tsx +++ b/frontend/src/features/Dashboard/components/DashboardForm/Columns/ThirdColumn.tsx @@ -1,5 +1,6 @@ import { RTK_DEFAULT_QUERY_OPTIONS } from '@api/constants' import { useGetControlUnitsQuery } from '@api/controlUnitsAPI' +import { useObserverAccordion } from '@features/Dashboard/hooks/useObserverAccordion' import { type DashboardType } from '@features/Dashboard/slice' import { Dashboard } from '@features/Dashboard/types' import { isNotArchived } from '@utils/isNotArchived' @@ -11,7 +12,6 @@ import { Weather } from '../Weather' import { BaseColumn } from './style' import { type ColumnProps } from './utils' import { type BookmarkType, Bookmark } from '../Bookmark' -import { useObserverAccordion } from '../useObserverAccordion' type ThirdColumnProps = { dashboardForm: [string, DashboardType] diff --git a/frontend/src/features/Dashboard/components/DashboardForm/Reportings/index.tsx b/frontend/src/features/Dashboard/components/DashboardForm/Reportings/index.tsx index a60305f94..0da949dc6 100644 --- a/frontend/src/features/Dashboard/components/DashboardForm/Reportings/index.tsx +++ b/frontend/src/features/Dashboard/components/DashboardForm/Reportings/index.tsx @@ -1,6 +1,7 @@ import { useGetReportingsByIdsQuery } from '@api/reportingsAPI' import { pluralize } from '@mtes-mct/monitor-ui' import { forwardRef, useEffect, useState } from 'react' +import styled from 'styled-components' import { Accordion } from '../Accordion' import { SelectedAccordion } from '../SelectedAccordion' @@ -36,7 +37,7 @@ export const Reportings = forwardRef( title="Signalements" titleRef={ref} > - + {reportings?.map(reporting => ( ))} @@ -58,3 +59,8 @@ export const Reportings = forwardRef( ) } ) + +const StyledFilters = styled(Filters)<{ $isExpanded: boolean }>` + visibility: ${({ $isExpanded }) => ($isExpanded ? 'visible' : 'hidden')}; + transition-delay: ${({ $isExpanded }) => ($isExpanded ? '0.5s visibility' : '0')}; +` diff --git a/frontend/src/features/Dashboard/components/DashboardForm/slice.ts b/frontend/src/features/Dashboard/components/DashboardForm/slice.ts index 5621c7af0..f28526fd6 100644 --- a/frontend/src/features/Dashboard/components/DashboardForm/slice.ts +++ b/frontend/src/features/Dashboard/components/DashboardForm/slice.ts @@ -1,5 +1,5 @@ import { createSelector, createSlice, type PayloadAction } from '@reduxjs/toolkit' -import { ReportingDateRangeEnum } from 'domain/entities/dateRange' +import { DateRangeEnum } from 'domain/entities/dateRange' import { StatusFilterEnum } from 'domain/entities/reporting' import { set } from 'lodash' import { persistReducer } from 'redux-persist' @@ -14,7 +14,7 @@ const persistConfig = { } export type ReportingFilters = { - dateRange: ReportingDateRangeEnum + dateRange: DateRangeEnum period?: DateAsStringRange status: StatusFilterEnum[] } @@ -34,6 +34,14 @@ export type DashboardFilters = { vigilanceAreaPeriod?: VigilanceArea.VigilanceAreaFilterPeriod | undefined } +export type DashboardsListFilters = { + controlUnits: number[] + regulatoryThemes: string[] + seaFronts: string[] + specificPeriod?: DateAsStringRange + updatedAt: DateRangeEnum +} + export type DashboardFiltersType = { controlUnitFilters: ControlUnitFilters filters: DashboardFilters @@ -44,9 +52,20 @@ type DashboardFiltersState = { dashboards: { [key: string]: DashboardFiltersType } + filters: DashboardsListFilters +} + +export const INITIAL_LIST_FILTERS_STATE: DashboardsListFilters = { + controlUnits: [], + regulatoryThemes: [], + seaFronts: [], + specificPeriod: undefined, + updatedAt: DateRangeEnum.MONTH } + const INITIAL_STATE: DashboardFiltersState = { - dashboards: {} + dashboards: {}, + filters: INITIAL_LIST_FILTERS_STATE } export const dashboardFiltersSlice = createSlice({ initialState: INITIAL_STATE, @@ -58,7 +77,7 @@ export const dashboardFiltersSlice = createSlice({ controlUnitFilters: {}, filters: {}, reportingFilters: { - dateRange: ReportingDateRangeEnum.MONTH, + dateRange: DateRangeEnum.MONTH, status: [StatusFilterEnum.IN_PROGRESS] } } @@ -78,6 +97,9 @@ export const dashboardFiltersSlice = createSlice({ state.dashboards[id].filters = {} } }, + resetFilters(state) { + state.filters = INITIAL_LIST_FILTERS_STATE + }, setControlUnitsFilters( state, action: PayloadAction<{ @@ -103,7 +125,7 @@ export const dashboardFiltersSlice = createSlice({ controlUnitFilters: {}, filters: {}, reportingFilters: { - dateRange: ReportingDateRangeEnum.MONTH, + dateRange: DateRangeEnum.MONTH, status: [StatusFilterEnum.IN_PROGRESS] } } @@ -117,6 +139,9 @@ export const dashboardFiltersSlice = createSlice({ state.dashboards[id].filters = { ...state.dashboards[id].filters, ...filters } } }, + setListFilters(state, action: PayloadAction>) { + state.filters = { ...state.filters, ...action.payload } + }, setReportingFilters(state, action: PayloadAction<{ filters: Partial; id: string | undefined }>) { const { filters, id } = action.payload if (!id) { @@ -126,6 +151,15 @@ export const dashboardFiltersSlice = createSlice({ const { reportingFilters } = state.dashboards[id] state.dashboards[id].reportingFilters = { ...reportingFilters, ...filters } } + }, + updateFilters: ( + state, + action: PayloadAction<{ + key: keyof DashboardsListFilters + value: any + }> + ) => { + state.filters[action.payload.key] = action.payload.value } } }) diff --git a/frontend/src/features/Dashboard/components/DashboardsList/Filters.tsx b/frontend/src/features/Dashboard/components/DashboardsList/Filters.tsx new file mode 100644 index 000000000..f9153689f --- /dev/null +++ b/frontend/src/features/Dashboard/components/DashboardsList/Filters.tsx @@ -0,0 +1,273 @@ +import { RTK_DEFAULT_QUERY_OPTIONS } from '@api/constants' +import { useGetControlUnitsQuery } from '@api/controlUnitsAPI' +import { useGetRegulatoryLayersQuery } from '@api/regulatoryLayersAPI' +import { TagsContainer } from '@components/style' +import { ReinitializeFiltersButton } from '@features/commonComponents/ReinitializeFiltersButton' +import { StyledSelect } from '@features/Reportings/Filters/style' +import { useAppDispatch } from '@hooks/useAppDispatch' +import { useAppSelector } from '@hooks/useAppSelector' +import { + CheckPicker, + CustomSearch, + DateRangePicker, + getOptionsFromIdAndName, + SingleTag, + type DateAsStringRange, + type OptionValueType +} from '@mtes-mct/monitor-ui' +import { isNotArchived } from '@utils/isNotArchived' +import { DateRangeEnum, dateRangeOptions } from 'domain/entities/dateRange' +import { getTitle } from 'domain/entities/layers/utils' +import { SeaFrontLabels } from 'domain/entities/seaFrontType' +import { isArray, isEqual, uniq } from 'lodash' +import { useMemo } from 'react' +import styled from 'styled-components' + +import { dashboardFiltersActions, INITIAL_LIST_FILTERS_STATE, type DashboardsListFilters } from '../DashboardForm/slice' + +type Orientation = 'row' | 'column' +export function Filters({ orientation = 'row' }: { orientation?: Orientation }) { + const dispatch = useAppDispatch() + const { controlUnits, regulatoryThemes, seaFronts, specificPeriod, updatedAt } = useAppSelector( + state => state.dashboardFilters.filters + ) + const seaFrontsAsOptions = Object.values(SeaFrontLabels) + + const { data: allControlUnits } = useGetControlUnitsQuery(undefined, RTK_DEFAULT_QUERY_OPTIONS) + const activeControlUnitsOptions = useMemo( + () => getOptionsFromIdAndName(allControlUnits?.filter(isNotArchived)), + [allControlUnits] + ) + const updateSeaFrontFilter = (nextValue: string[] | undefined) => { + dispatch(dashboardFiltersActions.setListFilters({ seaFronts: nextValue ?? [] })) + } + const resetFilter = () => { + dispatch(dashboardFiltersActions.resetFilters()) + } + const updateControlUnitFilter = (nextValue: number[] | undefined) => { + dispatch(dashboardFiltersActions.setListFilters({ controlUnits: nextValue ?? [] })) + } + const updateRegulatoryThemesFilter = (nextValue: string[] | undefined) => { + dispatch(dashboardFiltersActions.setListFilters({ regulatoryThemes: nextValue ?? [] })) + } + const updateUpdatedAtFilter = (nextValue: OptionValueType | undefined) => { + const value = nextValue as DateRangeEnum + dispatch(dashboardFiltersActions.setListFilters({ updatedAt: value })) + } + const updateUpdateAtSpecificPeriodFilter = (nextValue: DateAsStringRange | undefined) => { + dispatch(dashboardFiltersActions.setListFilters({ specificPeriod: nextValue })) + } + const controlUnitCustomSearch = useMemo( + () => new CustomSearch(activeControlUnitsOptions ?? [], ['label'], { isStrict: true, threshold: 0.2 }), + [activeControlUnitsOptions] + ) + + const { data: allRegulatoryLayers } = useGetRegulatoryLayersQuery() + + const regulatoryThemesOptions = useMemo( + () => + uniq(Object.values(allRegulatoryLayers?.entities ?? []).map(regulatoryLayer => regulatoryLayer.layer_name)) + .sort() + .map(layerName => ({ + label: getTitle(layerName), + value: layerName + })), + [allRegulatoryLayers] + ) + + const regulatoryThemesCustomSearch = useMemo( + () => new CustomSearch(regulatoryThemesOptions, ['label']), + [regulatoryThemesOptions] + ) + + const onDeleteTag = ( + valueToDelete: string | number, + filterKey: keyof DashboardsListFilters, + filter: (string | number)[] | string + ) => { + let updatedFilter: (string | number)[] | string | undefined = filter + + if (isArray(filter)) { + updatedFilter = filter.filter(unit => unit !== valueToDelete) + } + dispatch( + dashboardFiltersActions.updateFilters({ + key: filterKey, + value: updatedFilter + }) + ) + } + + const hasFilters = !isEqual(INITIAL_LIST_FILTERS_STATE, { + controlUnits, + regulatoryThemes, + seaFronts, + specificPeriod, + updatedAt + }) + + const seaFrontTags = ( + <> + {seaFronts?.map(seaFront => ( + onDeleteTag(seaFront, 'seaFronts', seaFronts)}> + {String(`Façade ${seaFront}`)} + + ))} + + ) + + const controlUnitTags = ( + <> + {controlUnits?.map(controlUnit => ( + onDeleteTag(controlUnit, 'controlUnits', controlUnits)}> + {String(`Unité ${allControlUnits?.find(control => control.id === controlUnit)?.name}`)} + + ))} + + ) + + const regulatoryThemesTags = ( + <> + {regulatoryThemes?.map(regulatoryTheme => ( + onDeleteTag(regulatoryTheme, 'regulatoryThemes', regulatoryThemes)} + > + {String(`Thématique réglementaire ${getTitle(regulatoryTheme)}`)} + + ))} + + ) + + const specificPeriodDatePicker = ( + <> + {updatedAt === DateRangeEnum.CUSTOM && ( + + )} + + ) + + return ( + + + + + {orientation === 'column' && specificPeriodDatePicker} + + + seaFronts && {`Façade (${seaFronts.length})`}} + style={{ width: 181 }} + value={seaFronts} + /> + {orientation === 'column' && seaFrontTags} + + + controlUnits && {`Unité (${controlUnits.length})`}} + style={{ width: 200 }} + value={controlUnits} + /> + {orientation === 'column' && controlUnitTags} + + + + regulatoryThemes && {`Thématique réglementaire (${regulatoryThemes.length})`} + } + style={{ width: 320 }} + value={regulatoryThemes} + /> + {orientation === 'column' && regulatoryThemesTags} + + + + {orientation === 'row' && [specificPeriodDatePicker, seaFrontTags, controlUnitTags, regulatoryThemesTags]} + + {hasFilters && } + + + ) +} + +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 16px; + padding: 12px 4px; +` + +const FiltersContainer = styled.div<{ $orientation: Orientation }>` + align-items: center; + display: flex; + flex-wrap: wrap; + + ${p => (p.$orientation === 'column' ? 'gap: 8px;' : 'gap: 16px;')} +` + +const FilterWrapper = styled.div<{ $orientation: Orientation }>` + ${p => + p.$orientation === 'column' && + ` + display: flex; + flex-direction: column; + gap: 8px; + padding-bottom: 8px; + width: 100%; + + > * { + width: 100% !important; + } + `} +` +const OptionValue = styled.span` + display: flex; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +` diff --git a/frontend/src/features/Dashboard/components/DashboardsList/index.tsx b/frontend/src/features/Dashboard/components/DashboardsList/index.tsx index 773e02891..7b5df3a9f 100644 --- a/frontend/src/features/Dashboard/components/DashboardsList/index.tsx +++ b/frontend/src/features/Dashboard/components/DashboardsList/index.tsx @@ -1,24 +1,20 @@ -import { useGetDashboardsQuery } from '@api/dashboardsAPI' import { TotalResults } from '@components/Table/style' +import { useGetFilteredDashboardsQuery } from '@features/Dashboard/hooks/useGetFilteredDashboardsQuery' import { SideWindowContent } from '@features/SideWindow/style' import styled from 'styled-components' import { DashboardsTable } from './DashboardsTable' -import { TWO_MINUTES } from '../../../../constants' +import { Filters } from './Filters' export function DashboardsList() { - const { - data: dashboards, - isError, - isFetching, - isLoading - } = useGetDashboardsQuery(undefined, { pollingInterval: TWO_MINUTES }) + const { dashboards, isError, isFetching, isLoading } = useGetFilteredDashboardsQuery() return ( Tableaux de bord + {dashboards?.length ?? '0'} Tableau{dashboards && dashboards.length > 1 ? 'x' : ''} diff --git a/frontend/src/features/Dashboard/components/Layers/DashboardsLayer.tsx b/frontend/src/features/Dashboard/components/Layers/DashboardsLayer.tsx index 4fdcbaa4d..7d5dbf91a 100644 --- a/frontend/src/features/Dashboard/components/Layers/DashboardsLayer.tsx +++ b/frontend/src/features/Dashboard/components/Layers/DashboardsLayer.tsx @@ -1,4 +1,4 @@ -import { useGetDashboardsQuery } from '@api/dashboardsAPI' +import { useGetFilteredDashboardsQuery } from '@features/Dashboard/hooks/useGetFilteredDashboardsQuery' import { selectDashboardOnMap } from '@features/Dashboard/useCases/selectDashboardOnMap' import { useAppDispatch } from '@hooks/useAppDispatch' import { useAppSelector } from '@hooks/useAppSelector' @@ -24,7 +24,7 @@ export function DashboardsLayer({ map, mapClickEvent }: BaseMapChildrenProps) { const hasMapInteraction = useHasMapInteraction() const isLayerVisible = displayDashboardLayer && !hasMapInteraction - const { data: dashboards } = useGetDashboardsQuery() + const { dashboards } = useGetFilteredDashboardsQuery() const dashboardsVectorSourceRef = useRef(new VectorSource()) as MutableRefObject>> const dashboardsVectorLayerRef = useRef( diff --git a/frontend/src/features/Dashboard/components/MenuButton.tsx b/frontend/src/features/Dashboard/components/MenuButton.tsx index 137fdcdb8..1d9f5fa4a 100644 --- a/frontend/src/features/Dashboard/components/MenuButton.tsx +++ b/frontend/src/features/Dashboard/components/MenuButton.tsx @@ -13,6 +13,7 @@ import { DrawDashboard } from './DrawDashboard' import { dashboardActions } from '../slice' import { closeDrawDashboard } from '../useCases/closeDrawDashboard' import { resetDrawing } from '../useCases/resetDrawing' +import { Filters } from './DashboardsList/Filters' export function DashboardMenuButton() { const dispatch = useAppDispatch() @@ -75,6 +76,7 @@ export function DashboardMenuButton() { ) : ( + diff --git a/frontend/src/features/Dashboard/hooks/useGetFilteredDashboardsQuery.ts b/frontend/src/features/Dashboard/hooks/useGetFilteredDashboardsQuery.ts new file mode 100644 index 000000000..791db2627 --- /dev/null +++ b/frontend/src/features/Dashboard/hooks/useGetFilteredDashboardsQuery.ts @@ -0,0 +1,88 @@ +import { useGetDashboardsQuery } from '@api/dashboardsAPI' +import { useGetRegulatoryLayersQuery } from '@api/regulatoryLayersAPI' +import { useAppSelector } from '@hooks/useAppSelector' +import { customDayjs, type DateAsStringRange } from '@mtes-mct/monitor-ui' +import { DateRangeEnum } from 'domain/entities/dateRange' +import { useMemo } from 'react' + +import { TWO_MINUTES } from '../../../constants' + +export const useGetFilteredDashboardsQuery = (skip = false) => { + const { controlUnits, regulatoryThemes, seaFronts, specificPeriod, updatedAt } = useAppSelector( + state => state.dashboardFilters.filters + ) + const { data: regulatoryAreas } = useGetRegulatoryLayersQuery() + + const { + data: dashboards, + isError, + isFetching, + isLoading + } = useGetDashboardsQuery(undefined, { + pollingInterval: TWO_MINUTES, + skip + }) + + const filteredDashboards = useMemo( + () => + dashboards + ?.filter(dashboard => seaFronts.length === 0 || (dashboard.seaFront && seaFronts.includes(dashboard.seaFront))) + .filter( + dashboard => + controlUnits.length === 0 || dashboard.controlUnitIds.some(control => controlUnits.includes(control)) + ) + .filter(dashboard => { + if (regulatoryThemes.length === 0) { + return true + } + + const filteredRegulatoryAreas = Object.values(regulatoryAreas?.entities ?? []).filter(regulatoryArea => + dashboard.regulatoryAreaIds?.includes(regulatoryArea.id) + ) + + return filteredRegulatoryAreas.some(reg => regulatoryThemes.includes(reg.layer_name)) + }) + .filter(dashboard => isWithinPeriod(updatedAt, dashboard.updatedAt, specificPeriod)), + [controlUnits, dashboards, regulatoryAreas?.entities, regulatoryThemes, seaFronts, updatedAt, specificPeriod] + ) + + return { dashboards: filteredDashboards, isError, isFetching, isLoading } +} + +function isWithinPeriod( + dateRange: DateRangeEnum | undefined, + date: string | undefined, + specificPeriod: DateAsStringRange | undefined +): boolean { + if (!dateRange) { + return true + } + const now = customDayjs().utc() + const dateAsDayJs = customDayjs(date).utc() + switch (dateRange) { + case DateRangeEnum.DAY: { + return dateAsDayJs.isBetween(now, now.startOf('day')) + } + case DateRangeEnum.WEEK: { + return dateAsDayJs.isBetween(now, now.startOf('day').subtract(1, 'week')) + } + case DateRangeEnum.MONTH: { + return dateAsDayJs.isBetween(now, now.startOf('day').subtract(1, 'month')) + } + case DateRangeEnum.YEAR: { + return dateAsDayJs.isBetween(now, now.startOf('year')) + } + case DateRangeEnum.CUSTOM: { + if (!specificPeriod) { + return true + } + + return dateAsDayJs.isBetween( + customDayjs(specificPeriod[0]).utc().startOf('day'), + customDayjs(specificPeriod[1]).utc().endOf('day') + ) + } + default: + return true + } +} diff --git a/frontend/src/features/Dashboard/components/DashboardForm/useObserverAccordion.tsx b/frontend/src/features/Dashboard/hooks/useObserverAccordion.tsx similarity index 97% rename from frontend/src/features/Dashboard/components/DashboardForm/useObserverAccordion.tsx rename to frontend/src/features/Dashboard/hooks/useObserverAccordion.tsx index 281159fcd..b225f06e4 100644 --- a/frontend/src/features/Dashboard/components/DashboardForm/useObserverAccordion.tsx +++ b/frontend/src/features/Dashboard/hooks/useObserverAccordion.tsx @@ -1,7 +1,7 @@ import { debounce } from 'lodash' import { useEffect, useMemo } from 'react' -import type { BookmarkType } from './Bookmark' +import type { BookmarkType } from '../components/DashboardForm/Bookmark' const checkVisibility = ( container: HTMLElement | null,