Duplicating a View (SkySpark)

  1. To duplicate a user's View in Periscope in order to avoid recreating specific styles and layouts used on another View, the user will need to access the the Folio app in their SkySpark instance:

  2. Obtaining the id for the view is as easy as inspecting the URL while on the view you wish to duplicate. The ID for the view immediately follows "view" in the URL. For instance the view id for the URL: "/api/demo/ext/periscope/#/view/p:demo:r:21af3bb6-49c05b37" would be "p:demo:r:21af3bb6-49c05b37".

  3. To copy the view to a new user you will need the ID for the user you wish to copy the view to. This can be obtained through the Folio app as well by querying for all periscope user records with:

    readAll(periscope and user)

    The user you are copying to must have logged in first to exist in the Folio database

  4. Now, with the new user ID: invoke the following command (where id_of_user is the fully qualified ID of the other user you are copying to - like @p:demo:r:otherUser - and the with the id of the view you're trying to copy):

    copyViewInstanceToUser(readById(@id_of_viewInstance), readById(@id_of_user))
  5. The duplicated view will now appear in the user's View Manager in the dashboard Settings page. Note that the "context" of the View and all relative links and information will attempt to remain the same. The user will need to edit these items as necessary. 

Understanding how the AXON view copying works isn't required, but for the curious - here is a breakdown of it step by step:

readAll(id==viewInstance->id or viewInstanceRef==viewInstance->id)                          // 1
  .swizzleRefs                                                                              // 2
  .removeCol("mod")                                                                         // 3
  .map(r =>                                                                                 // 4
      if (r.has("userRef"))                                                                 // 5
        r.merge({userRef: otherUser->id}) 
      else
        r
  )
  .each(r => diff(null, r, { add }).commit)                                                 // 6
  1. readAll: Here we are capturing the viewletInstance making up our "view" that we are copying as well as all references to that viewletInstance - which makes up the viewlets belonging to the view. If we were to only execute our command on the view itself we'd lose all of our viewlets!
  2. swizzleRefs: is a SkySpark library function that takes all the IDs of all the records passed in via a grid and transforms those IDs to new IDs; this is necessary so that we have new IDs to add to our folio database (since we couldn't re-use the existing unique IDs). This function also ensures that all references that existed in the grid are maintained so that although our viewInstance is getting a new ID, all the viewInstanceRefs are updated to this new ID preserving what viewlets existed in our view.
  3. removeCol("mod"): this removes the SkySpark "mod" column that tracks modification dates for the record, these are new records being inserted so they can't have a pre-existing mod column.
  4. map(r => doStuff): map is a SkySpark Axon library function that takes in all the records in the grid and performs a transformation on them
  5. if statement: our if-statement takes any records with an existing userRef and transforms that userRef to be our new user that we are copying to (in this case "otherUserId"). Note that this user id will more likely look something like @p:project:r:user in the wild. In our case, the only record with a userRef is our viewInstance.
  6. each statement: here we are taking our final grid of results and creating a SkySpark Folio database "Diff" for each record so that we can then commit it to the database thus creating the new records for the user.