Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
port module GlobalPropertiesRecentActivity exposing (..)

import Activity.ActivityTable exposing (initTable)
import Activity.ApiCalls exposing (getActivities, processActivityApiError)
import Activity.DataTypes exposing (Activity, ActivityMsg(..), BodyParameters, ContextPath(..), string2Search)
import Browser
import Dict
import Html exposing (Html, div)
import Html.Attributes exposing (class)
import Rudder.Table exposing (updateData)
import Time exposing (Zone)
import TimeZone


port errorNotification : String -> Cmd msg


port copy : String -> Cmd msg


type GlobalPropertyId
= GlobalPropertyId String


type alias Model =
{ globalPropertyId : GlobalPropertyId
, activityTable : Rudder.Table.Model Activity Msg
, contextPath : ContextPath
, zone : Zone
}


type Msg
= CallApi (Model -> Cmd Msg)
| RudderTableMsg (Rudder.Table.Msg Msg)
| ActivityMessage ActivityMsg


init :
{ globalPropertyId : String
, contextPath : String
, timeZone : String
}
-> ( Model, Cmd Msg )
init flags =
let
initTimeZone =
Dict.get flags.timeZone TimeZone.zones
|> Maybe.withDefault (\() -> Time.utc)

zone =
initTimeZone ()

initModel : Model
initModel =
{ globalPropertyId = GlobalPropertyId flags.globalPropertyId
, activityTable = initTable zone
, contextPath = ContextPath flags.contextPath
, zone = zone
}

-- full text search on directive id to keep activity related to this directive
search =
string2Search flags.globalPropertyId

bodyParameters : BodyParameters
bodyParameters =
{ search = search

-- Keep only directive activity filtering on event log types
, filterTypes = [ "GlobalParameterAdded", "GlobalParameterDeleted", "GlobalParameterModified" ]
}

initActions =
[ Cmd.map ActivityMessage (getActivities bodyParameters initModel.contextPath) ]
in
( initModel, Cmd.batch initActions )



{- Table of the recent activity -}


table : Model -> Html Msg
table model =
div [ class "main-table" ] [ Html.map RudderTableMsg (Rudder.Table.view model.activityTable) ]


view : Model -> Html Msg
view model =
table model


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
CallApi call ->
( model, call model )

RudderTableMsg m ->
let
( activityTable, tableMsg, _ ) =
Rudder.Table.update m model.activityTable
in
( { model | activityTable = activityTable }, tableMsg )

ActivityMessage a ->
case a of
GetActivities res ->
case res of
-- Update table data
Ok ( _, activities ) ->
let
updatedTable =
updateData activities model.activityTable
in
( { model | activityTable = updatedTable }, Cmd.none )

Err err ->
( model, processActivityApiError "Getting activities list" err errorNotification )

CopyToClipboard s ->
( model, copy s )


subscriptions _ =
Sub.none


main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,18 @@ class ParameterManagement extends SecureDispatchSnippet with Loggable {
"pageLength": 25
});""") &
JsRaw(s"""
/* Formating function for row details */

/* Formating function for row details */
function fnFormatDetails(id) {
const sOut = '<span id="'+id+'" class="parametersDescriptionDetails"/>';
return sOut;
};

function fnFormatActivity(id) {
// FIXME : add some CSS for activity table from elm app

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed, i think the CSS should be modified : i think the table should have a border and empty space all around it in order to separate it from the rest

Image

did you have other ideas @P4uline ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's acceptable that you modify it in another PR, that's a kind of iterative fix/improvement you can do in alpha

return '<span><ul class="ms-2"><li><b>Recent activity:</b></li></ul></span><div class="parametersDescriptionDetails"><div id="globalPropertiesRecentActivityApp"></div></div>'
};

${jsVarNameForId(gridName)}.rows().nodes().to$$().each( function () {
$$(this).click( function (event) {
const jTr = $$(this);
Expand All @@ -231,12 +237,45 @@ class ParameterManagement extends SecureDispatchSnippet with Loggable {
color = 'color2';
const row = ${jsVarNameForId(
gridName
)}.row(this).child(fnFormatDetails(jsid), color + ' parametersDescription details').show();
)}.row(this);

const globalPropertyName = jTr.find('td.name').find('b').html();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be nice to fetch the name of the property in a more robust way eventually.
fetching the name of the property in this way would not be necessary had the entire global properties table been contained in a single Elm app, but migrating it to Elm is not really feasible with the current state of the Rudder.Table module as it does not support many of the key features of the properties table.

in the meantime, do you see a cleaner way of fetching the property name @clarktsiory @RaphaelGauthier ?

@clarktsiory clarktsiory Aug 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely agree that it's not ideal to rely on potentially unstable CSS selectors (such as b) to find the name of the global property... The current td.name looks fine to me, but I'd prefer directly find('td.name').text() with further sanitization.

As for a cleaner way to do that, I don't know any other solution than CSS selectors at this level...


// row child show is from datatable API
const children = [fnFormatDetails(jsid)];

if (globalPropertyName !== 'rudder') {
/* Don't show recent activity for rudder global property.

The 'rudder' global property is created by the system and cannot be modified so it doesn't have any
activity logged therefore we don't want to add an empty table for this property.
*/
children.push(fnFormatActivity(jsid));
}

row.child(children, color + ' parametersDescription details');
row.show();
$$('#'+jsid).html($$('#description-'+jsid).html());


const recentActivityMain = document.getElementById("globalPropertiesRecentActivityApp")
const initValues = {
globalPropertyId : globalPropertyName,
contextPath : contextPath,
timeZone : localStorage.getItem('timeZone') ?? 'UTC'
};

const app = Elm.GlobalPropertiesRecentActivity.init({node: recentActivityMain, flags: initValues});
app.ports.errorNotification.subscribe(function(str) {
createErrorNotification(str)
});
}
}
} );
})""") // JsRaw ok, const
}
});
})


""") // JsRaw ok, const
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
content: "";
}
</style>
<script data-lift="with-cached-resource" src="/javascript/rudder/elm/rudder-globalpropertiesrecentactivity.js"></script>
</head>

<div class="rudder-template">
Expand Down
Loading