In this post I will show you how you can customise the Environment Variables custom page in the COE Starter Kit to create a single page that shows all your environment variables across environments.
Within the Starter Kit there is a model driven app called COE Admin Command Center and within that app is a page that allows you to view and edit environment variables in the current COE environment.
We will copy this page and turn it into a multi environment view of environment variables.
Step 1 - Create a Copy of the COE Environment Variable page
Edit the CoE Admin Command Center and edit the COE Environment Variables Page: Create a copy of the page by using Save As Give your page a new name and press save
Step 2 - Create the Environments Pivot
Copy the Container with the Pivot control and move it just below the header
For the newly copied Pivot change the items to the environments you want to manage for example.
Table(
{
ItemDisplayName: "COE",
ItemKey: "coe"
},
{
ItemDisplayName: "POWR Statto - Dev",
ItemKey: "dev"
},
{
ItemDisplayName: "POWR Statto - Test",
ItemKey: "uat"
},
{
ItemDisplayName: "Statto",
ItemKey: "prod"
}
)
Next in the container with our Environments pivot add a Button control and change its text and Name to fnGetVariables.
In our newly created environments Pivot_1 controls OnSelect add the select function Select(fnGetVariables);
Select the OnVisible parameter of Screen1 and Cut the following code and copy it to the OnSelect of our button fnGetVariables:
Clear(AugmentedVariables);
ForAll(
Filter(
'Environment Variable Definitions',
"admin_" in 'Schema Name'
),
Collect(
AugmentedVariables,
{
DefnID: 'Environment Variable Definition',
CurrentID: "xxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx",
SchemaName: 'Schema Name',
DisplayName: 'Display Name',
Description: Description,
DefaultValue: 'Default Value',
CurrentValue: "",
DisplayValue: "",
hasDefault: If(
IsBlank('Default Value'),
false,
true
),
hasCurrent: false,
hasValue: false,
customizedColor: ColorNo,
customizedIcon: "icon:SkypeCircleCheck",
isSecretType: If(
Type = 'Type (Environment Variable Definitions)'.Secret,
true,
false
)
}
)
);
UpdateIf(
AugmentedVariables,
true,
{
CurrentID: LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).'Environment Variable Value',
CurrentValue: LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value,
hasCurrent: If(
IsBlank(
LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
false,
true
),
customizedColor: If(
IsBlank(
LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
ColorNo,
ColorYes
),
customizedIcon: If(
IsBlank(
LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
"",
"icon:SkypeCircleCheck"
),
DisplayValue: If(
!IsBlank(
LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value,
DefaultValue
),
hasValue: If(
IsBlank(DefaultValue) && IsBlank(
LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
false,
true
)
}
);
Where you cut the code add the Select(fnGetVariables); command, this will call our button.
Step 3 - Create Connections to each environment.
We need to add 2 tables from each of the environments you want to add.
Add data sources for each environment by selecting the Change Environment option and adding the tables Environment Variable Definitions and Environment Variable Values.
Do this for each environment.
Step 4 - Add a Switch statement to the fnGetVariables button.
In the button’s OnSelect parameter, use a switch statement to select the appropriate environment and populate the variables accordingly.
Switch(
Pivot_1.Selected.ItemKey,
"dev",
Clear(AugmentedVariables);
ForAll(
'Environment Variable Definitions_1',
Collect(
AugmentedVariables,
{
DefnID: 'Environment Variable Definition',
CurrentID: "xxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx",
SchemaName: 'Schema Name',
DisplayName: 'Display Name',
Description: Description,
DefaultValue: 'Default Value',
CurrentValue: "",
DisplayValue: "",
hasDefault: If(
IsBlank('Default Value'),
false,
true
),
hasCurrent: false,
hasValue: false,
customizedColor: ColorNo,
customizedIcon: "icon:SkypeCircleCheck",
isSecretType: If(
Type = 'Type (Environment Variable Definitions_1)'.Secret,
true,
false
)
}
)
);
UpdateIf(
AugmentedVariables,
true,
{
CurrentID: LookUp(
'Environment Variable Values_1',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).'Environment Variable Value',
CurrentValue: LookUp(
'Environment Variable Values_1',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value,
hasCurrent: If(
IsBlank(
LookUp(
'Environment Variable Values_1',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
false,
true
),
customizedColor: If(
IsBlank(
LookUp(
'Environment Variable Values_1',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
ColorNo,
ColorYes
),
customizedIcon: If(
IsBlank(
LookUp(
'Environment Variable Values_1',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
"",
"icon:SkypeCircleCheck"
),
DisplayValue: If(
!IsBlank(
LookUp(
'Environment Variable Values_1',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
LookUp(
'Environment Variable Values_1',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value,
DefaultValue
),
hasValue: If(
IsBlank(DefaultValue) && IsBlank(
LookUp(
'Environment Variable Values_1',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
false,
true
)
}
);
,
"uat",
Clear(AugmentedVariables);
ForAll(
'Environment Variable Definitions_2',
Collect(
AugmentedVariables,
{
DefnID: 'Environment Variable Definition',
CurrentID: "xxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx",
SchemaName: 'Schema Name',
DisplayName: 'Display Name',
Description: Description,
DefaultValue: 'Default Value',
CurrentValue: "",
DisplayValue: "",
hasDefault: If(
IsBlank('Default Value'),
false,
true
),
hasCurrent: false,
hasValue: false,
customizedColor: ColorNo,
customizedIcon: "icon:SkypeCircleCheck",
isSecretType: If(
Type = 'Type (Environment Variable Definitions_2)'.Secret,
true,
false
)
}
)
);
UpdateIf(
AugmentedVariables,
true,
{
CurrentID: LookUp(
'Environment Variable Values_2',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).'Environment Variable Value',
CurrentValue: LookUp(
'Environment Variable Values_2',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value,
hasCurrent: If(
IsBlank(
LookUp(
'Environment Variable Values_2',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
false,
true
),
customizedColor: If(
IsBlank(
LookUp(
'Environment Variable Values_2',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
ColorNo,
ColorYes
),
customizedIcon: If(
IsBlank(
LookUp(
'Environment Variable Values_2',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
"",
"icon:SkypeCircleCheck"
),
DisplayValue: If(
!IsBlank(
LookUp(
'Environment Variable Values_2',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
LookUp(
'Environment Variable Values_2',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value,
DefaultValue
),
hasValue: If(
IsBlank(DefaultValue) && IsBlank(
LookUp(
'Environment Variable Values_2',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
false,
true
)
}
);
,
"prod",
Clear(AugmentedVariables);
ForAll(
'Environment Variable Definitions_3',
Collect(
AugmentedVariables,
{
DefnID: 'Environment Variable Definition',
CurrentID: "xxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx",
SchemaName: 'Schema Name',
DisplayName: 'Display Name',
Description: Description,
DefaultValue: 'Default Value',
CurrentValue: "",
DisplayValue: "",
hasDefault: If(
IsBlank('Default Value'),
false,
true
),
hasCurrent: false,
hasValue: false,
customizedColor: ColorNo,
customizedIcon: "icon:SkypeCircleCheck",
isSecretType: If(
Type = 'Type (Environment Variable Definitions_3)'.Secret,
true,
false
)
}
)
);
UpdateIf(
AugmentedVariables,
true,
{
CurrentID: LookUp(
'Environment Variable Values_3',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).'Environment Variable Value',
CurrentValue: LookUp(
'Environment Variable Values_3',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value,
hasCurrent: If(
IsBlank(
LookUp(
'Environment Variable Values_3',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
false,
true
),
customizedColor: If(
IsBlank(
LookUp(
'Environment Variable Values_3',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
ColorNo,
ColorYes
),
customizedIcon: If(
IsBlank(
LookUp(
'Environment Variable Values_3',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
"",
"icon:SkypeCircleCheck"
),
DisplayValue: If(
!IsBlank(
LookUp(
'Environment Variable Values_3',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
LookUp(
'Environment Variable Values_3',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value,
DefaultValue
),
hasValue: If(
IsBlank(DefaultValue) && IsBlank(
LookUp(
'Environment Variable Values_3',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
false,
true
)
}
);
,
"coe",
Clear(AugmentedVariables);
ForAll(
Filter(
'Environment Variable Definitions',
"admin_" in 'Schema Name'
),
Collect(
AugmentedVariables,
{
DefnID: 'Environment Variable Definition',
CurrentID: "xxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx",
SchemaName: 'Schema Name',
DisplayName: 'Display Name',
Description: Description,
DefaultValue: 'Default Value',
CurrentValue: "",
DisplayValue: "",
hasDefault: If(
IsBlank('Default Value'),
false,
true
),
hasCurrent: false,
hasValue: false,
customizedColor: ColorNo,
customizedIcon: "icon:SkypeCircleCheck",
isSecretType: If(
Type = 'Type (Environment Variable Definitions)'.Secret,
true,
false
)
}
)
);
UpdateIf(
AugmentedVariables,
true,
{
CurrentID: LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).'Environment Variable Value',
CurrentValue: LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value,
hasCurrent: If(
IsBlank(
LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
false,
true
),
customizedColor: If(
IsBlank(
LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
ColorNo,
ColorYes
),
customizedIcon: If(
IsBlank(
LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
"",
"icon:SkypeCircleCheck"
),
DisplayValue: If(
!IsBlank(
LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value,
DefaultValue
),
hasValue: If(
IsBlank(DefaultValue) && IsBlank(
LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = DefnID
).Value
),
false,
true
)
}
);
)
Just make sure each environment matches with the connections you made.
Select the Button and change it’s Visible property to false, we don’t need to see it!
Step 5 - Update the Title Text
Select the header lbl text control and change it’s text value to $"{Pivot_1.Selected.ItemDisplayName} Environment Variables"
Step 6 - Update the Edit and Revert functions.
When you select an Environment Variable you can edit or revert the values by clicking the Edit button in the header, this opens a side panel in which we need to update the OnButtonSelect to the following code to allow updates across environments:
Switch(
Self.SelectedButton.Label,
"Save",
Switch(
Pivot_1.Selected.ItemKey,
"coe",
//if current value exists, update it in data source and collection
If(
EnvVarsList.Selected.hasCurrent = true,
UpdateIf(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = EnvVarsList.Selected.DefnID,
{Value: value_textbox.Value}
);
UpdateIf(
AugmentedVariables,
DefnID = EnvVarsList.Selected.DefnID,
{
CurrentValue: value_textbox.Value,
DisplayValue: value_textbox.Value,
hasCurrent: true,
hasValue: true,
customizedIcon: "icon:SkypeCircleCheck",
customizedColor: ColorYes
}
);
,
//else insert new current value
UpdateContext(
{
newCurrentValueID: Patch(
'Environment Variable Values',
Defaults('Environment Variable Values'),
{
'Schema Name': EnvVarsList.Selected.SchemaName,
Value: value_textbox.Value
}
)
}
);
UpdateIf(
AugmentedVariables,
DefnID = EnvVarsList.Selected.DefnID,
{
CurrentValue: value_textbox.Value,
DisplayValue: value_textbox.Value,
hasCurrent: true,
hasValue: true,
customizedIcon: "icon:SkypeCircleCheck",
customizedColor: ColorYes,
CurrentID: newCurrentValueID.'Environment Variable Value'
}
);
UpdateContext({x: "y"})
);
//bug in powerfx?? need this here or error
//close panel
UpdateContext({showPanel: false}),
"dev",
//if current value exists, update it in data source and collection
If(
EnvVarsList.Selected.hasCurrent = true,
UpdateIf(
'Environment Variable Values_1',
'Environment Variable Definition'.'Environment Variable Definition' = EnvVarsList.Selected.DefnID,
{Value: value_textbox.Value}
);
UpdateIf(
AugmentedVariables,
DefnID = EnvVarsList.Selected.DefnID,
{
CurrentValue: value_textbox.Value,
DisplayValue: value_textbox.Value,
hasCurrent: true,
hasValue: true,
customizedIcon: "icon:SkypeCircleCheck",
customizedColor: ColorYes
}
);
,
//else insert new current value
UpdateContext(
{
newCurrentValueID: Patch(
'Environment Variable Values_1',
Defaults('Environment Variable Values_1'),
{
'Schema Name': EnvVarsList.Selected.SchemaName,
Value: value_textbox.Value
}
)
}
);
UpdateIf(
AugmentedVariables,
DefnID = EnvVarsList.Selected.DefnID,
{
CurrentValue: value_textbox.Value,
DisplayValue: value_textbox.Value,
hasCurrent: true,
hasValue: true,
customizedIcon: "icon:SkypeCircleCheck",
customizedColor: ColorYes,
CurrentID: newCurrentValueID.'Environment Variable Value'
}
);
UpdateContext({x: "y"})
);
//bug in powerfx?? need this here or error
//close panel
UpdateContext({showPanel: false}),
"uat",
//if current value exists, update it in data source and collection
If(
EnvVarsList.Selected.hasCurrent = true,
UpdateIf(
'Environment Variable Values_2',
'Environment Variable Definition'.'Environment Variable Definition' = EnvVarsList.Selected.DefnID,
{Value: value_textbox.Value}
);
UpdateIf(
AugmentedVariables,
DefnID = EnvVarsList.Selected.DefnID,
{
CurrentValue: value_textbox.Value,
DisplayValue: value_textbox.Value,
hasCurrent: true,
hasValue: true,
customizedIcon: "icon:SkypeCircleCheck",
customizedColor: ColorYes
}
);
,
//else insert new current value
UpdateContext(
{
newCurrentValueID: Patch(
'Environment Variable Values_2',
Defaults('Environment Variable Values_2'),
{
'Schema Name': EnvVarsList.Selected.SchemaName,
Value: value_textbox.Value
}
)
}
);
UpdateIf(
AugmentedVariables,
DefnID = EnvVarsList.Selected.DefnID,
{
CurrentValue: value_textbox.Value,
DisplayValue: value_textbox.Value,
hasCurrent: true,
hasValue: true,
customizedIcon: "icon:SkypeCircleCheck",
customizedColor: ColorYes,
CurrentID: newCurrentValueID.'Environment Variable Value'
}
);
UpdateContext({x: "y"})
);
//bug in powerfx?? need this here or error
//close panel
UpdateContext({showPanel: false}),
"prod",
//if current value exists, update it in data source and collection
If(
EnvVarsList.Selected.hasCurrent = true,
UpdateIf(
'Environment Variable Values_3',
'Environment Variable Definition'.'Environment Variable Definition' = EnvVarsList.Selected.DefnID,
{Value: value_textbox.Value}
);
UpdateIf(
AugmentedVariables,
DefnID = EnvVarsList.Selected.DefnID,
{
CurrentValue: value_textbox.Value,
DisplayValue: value_textbox.Value,
hasCurrent: true,
hasValue: true,
customizedIcon: "icon:SkypeCircleCheck",
customizedColor: ColorYes
}
);
,
//else insert new current value
UpdateContext(
{
newCurrentValueID: Patch(
'Environment Variable Values_3',
Defaults('Environment Variable Values_3'),
{
'Schema Name': EnvVarsList.Selected.SchemaName,
Value: value_textbox.Value
}
)
}
);
UpdateIf(
AugmentedVariables,
DefnID = EnvVarsList.Selected.DefnID,
{
CurrentValue: value_textbox.Value,
DisplayValue: value_textbox.Value,
hasCurrent: true,
hasValue: true,
customizedIcon: "icon:SkypeCircleCheck",
customizedColor: ColorYes,
CurrentID: newCurrentValueID.'Environment Variable Value'
}
);
UpdateContext({x: "y"})
);
//bug in powerfx?? need this here or error
//close panel
UpdateContext({showPanel: false})
);
,//end save
"Revert",
Switch(
Pivot_1.Selected.ItemKey,
"coe",
If(
EnvVarsList.Selected.hasCurrent = false || EnvVarsList.Selected.hasDefault = false,
Notify("Nothing to revert, no alternate reset value exists.")
);
If(
EnvVarsList.Selected.hasCurrent = true && EnvVarsList.Selected.hasDefault = true,
RemoveIf(
'Environment Variable Values',
'Environment Variable Definition'.'Environment Variable Definition' = EnvVarsList.Selected.DefnID
);
UpdateIf(
AugmentedVariables,
SchemaName = EnvVarsList.Selected.SchemaName,
{
CurrentValue: "",
DisplayValue: EnvVarsList.Selected.DefaultValue,
hasCurrent: false,
hasValue: true,
CurrentID: "",
customizedColor: ColorNo,
customizedIcon: ""
}
);
);
//close panel
UpdateContext({showPanel: false});
,
"dev",
If(
EnvVarsList.Selected.hasCurrent = false || EnvVarsList.Selected.hasDefault = false,
Notify("Nothing to revert, no alternate reset value exists.")
);
If(
EnvVarsList.Selected.hasCurrent = true && EnvVarsList.Selected.hasDefault = true,
RemoveIf(
'Environment Variable Values_1',
'Environment Variable Definition'.'Environment Variable Definition' = EnvVarsList.Selected.DefnID
);
UpdateIf(
AugmentedVariables,
SchemaName = EnvVarsList.Selected.SchemaName,
{
CurrentValue: "",
DisplayValue: EnvVarsList.Selected.DefaultValue,
hasCurrent: false,
hasValue: true,
CurrentID: "",
customizedColor: ColorNo,
customizedIcon: ""
}
);
);
//close panel
UpdateContext({showPanel: false});
,
"uat",
If(
EnvVarsList.Selected.hasCurrent = false || EnvVarsList.Selected.hasDefault = false,
Notify("Nothing to revert, no alternate reset value exists.")
);
If(
EnvVarsList.Selected.hasCurrent = true && EnvVarsList.Selected.hasDefault = true,
RemoveIf(
'Environment Variable Values_2',
'Environment Variable Definition'.'Environment Variable Definition' = EnvVarsList.Selected.DefnID
);
UpdateIf(
AugmentedVariables,
SchemaName = EnvVarsList.Selected.SchemaName,
{
CurrentValue: "",
DisplayValue: EnvVarsList.Selected.DefaultValue,
hasCurrent: false,
hasValue: true,
CurrentID: "",
customizedColor: ColorNo,
customizedIcon: ""
}
);
);
//close panel
UpdateContext({showPanel: false});
,
"prod",
If(
EnvVarsList.Selected.hasCurrent = false || EnvVarsList.Selected.hasDefault = false,
Notify("Nothing to revert, no alternate reset value exists.")
);
If(
EnvVarsList.Selected.hasCurrent = true && EnvVarsList.Selected.hasDefault = true,
RemoveIf(
'Environment Variable Values_3',
'Environment Variable Definition'.'Environment Variable Definition' = EnvVarsList.Selected.DefnID
);
UpdateIf(
AugmentedVariables,
SchemaName = EnvVarsList.Selected.SchemaName,
{
CurrentValue: "",
DisplayValue: EnvVarsList.Selected.DefaultValue,
hasCurrent: false,
hasValue: true,
CurrentID: "",
customizedColor: ColorNo,
customizedIcon: ""
}
);
);
//close panel
UpdateContext({showPanel: false});
//end revert
)
)
Step 7 - Celebrate!
When you run the page, you’ll have a single page to manage environment variables across selected environments.
Key Takeaways
- Customized the COE Starter Kit for efficient environment variable management.
- Established connections to various environments within the custom page.
- Created a central hub for managing multiple environments in one place.
Building your Command and Control center for Dynamics/Power Platform, especially if you’ve implemented ALM or CI, is highly recommended.
I hope you find this post informative and helpful.
comments powered by Disqus
If you liked this post and would like to read more of my posts.
Subscribe