Default onError handler exposes internals on production

The default onError handler just outputs the error stack on production too, which IMO is a security concern, I think it would be much better if when process.env.NODE_ENV === 'production' it just returned a generic 500 error.
https://github.com/tinyhttp/tinyhttp/blob/08cff9e507ad8f4496a1181ea5e2b9d4baf50993/packages/app/src/onError.ts#L8-L16

erm, it doesn't output any error stack in the response, it only sends a respond message
I cannot "just return a generic 500 error" for multiple reasons

it will break no match handler
it will break all next calls where you pass an error with custom code

and so on
this is not a bug at all and is intended design
500 is already a default error code

erm, it doesn't output any error stack in the response, it only sends a respond message

Right, I misspoke, sorry. Still sending the raw error message on production is an issue IMO.

it will break no match handler

I don't see why noMatchHandler should be dependent on onError to being with though.

it will break all next calls where you pass an error with custom code (for example an error with 419 Unsupported Media Type)

🤔 One shouldn't be using errors to output custom body content to begin with, there are other, explicit, APIs for doing that. If an error happens on production you only want people seeing "Internal Server Error" at best.
FWIW that's how Express works if I remember correctly, and for good reasons IMO.

@fabiospampinato

Right, I misspoke, sorry. Still sending the raw error message on production is an issue IMO.

I don't understand the "raw" part. Error message is like a heading of the error, it's not the full message so there's no way to leak anything

I don't see why noMatchHandler should be dependent on onError to being with though.

because it's the simplest way to send 404 by default. 404 is an "error" somewhat, because it's an unsuccessful request.

🤔 One shouldn't be using errors to output custom body content to begin with, there are other, explicit, APIs for doing that. If an error happens on production you only want people seeing "Internal Server Error" at best.
FWIW that's how Express works if I remember correctly, and for good reasons IMO.

but that's not true, Express does that even in their own response extensions, see:
https://github.com/expressjs/express/blob/28db2c2c5cf992c897d1fbbc6b119ee02fe32ab1/lib/response.js#L679

I don't understand the "raw" part. Error message is like a heading of the error, it's not the full message so there's no way to leak anything

Not leaking ~anything means that either the same message is always returned or noise is always returned, returning actual error messages (forget about the "raw" part) is leaky.
Hypothetical obvious example: say I'm using really-stupid-mysql-client, if that library throws an error with the following message I'm screwed: "[really-stupid-mysql-client]: Server connection failed, are you sure the following username and passwords are correct: admin:pass ???".
That's just one obvious hypothetical problem outputting error messages on production allows for, but it can be more subtle than that, for example an error message might tell an attacker what libraries I'm using ("really-stupid-mysql-client" in this example), so they can try to find exploitable vulnerabilities in that immediately, or enough error messages could tell the attacker something interesting about the actual code I wrote that it's getting executed, which could allow them to evade some broken validation logic for example.
At the end of the day it's impossible to know for sure what errors might get outputted (nobody can read understand and vet tens of megabytes of dependencies), so they shouldn't be visible to users to begin with.

because it's the simplest way to send 404 by default. 404 is an "error" somewhat, because it's an unsuccessful request.

IMO though the library should optimize for code that works perfectly, not for code that's easy to write. In this particular code it seems to me like easy code gets in the way of correct code, so it should be changed.

but that's not true, Express does that even in their own response extensions, see:

On really? 🤔 I must be misremembering the behavior or the library I was using then 🤔 In any case, that's an issue for them too just the same.

On really? 🤔 I must be misremembering the behavior or the library I was using then 🤔 In any case, that's an issue for them too just the same.

maybe. tinyhttp tries to replicate Express so I won't change that.
and you should wrap all the errors properly, it's a responsibility of a developer, not the library's

and you should wrap all the errors properly, it's a responsibility of a developer, not the library's

That's kind of a silly argument if you think about it, every single function call into a dependency may throw as far as the developer knows, wrapping everything in try..catch blocks would be painful, and potentially you only need to mess up once to be screwed anyway. Making it impossible for such issues to arise is the obvious right solution. Authors of libraries like yours should take some responsibility and provide good defaults if they can.
Anyway of course this is your decision to make, from my personal point of view though I don't want to depend on security-critical code made my people that don't take security seriously, so I think unfortunately for me I'll have to move to something else.
Migrating from Express to TinyHTTP went fairly smoothly for me, overall I like what you are building, best of luck 👍.

@fabiospampinato to prove my point, Koa and Polka do absolutely the same with errors and no one shames them for that
it's a standard practice to put Error in next
and usually handlers aren't that big and use helper functions, where yes you should check for every function to be handled
"wrapping in try catch blocks would be painful"
idk what to say, everyone did that since the beginning of times
there are tons of other ways to do that
oh and also
you can supply your own onError handler to tinyhttp contructor in case you dislike the standard approach
const app = new App({
  onError: (err, req, res) => ...,
  notFound: (...) => ...
})

to prove my point, Koa and Polka do absolutely the same with errors and no one shames them for that.

I'm not interested in convincing you of this, but if somebody is making a mistake pointing at other famous people that make the same mistake changes nothing, it's still a mistake.

Well, you initially used express but that security issue didn't concern you at the time? I don't understand the logic behind that.

As I said I think having untrustworthy dependencies is a problem -> I moved from express to tinyhttp mainly because with that I'm relying on way less code (and from fewer people it seems) -> now that I'm learning about this problem I'm especially concerned about security with this too and I'm going to look into reducing the code I depend on further.
At the end of the day though I can't rewrite the world, I have to trust someone at some point, vetting all the code I depend on it's just not possible. Also the thing I was using express for previously, and tinyhttp currently, isn't particularly security critical yet, there's nothing of importance that could be stolen from there for example, this dependency pruning thing I'm going through is partially in preparation for when I'll have the server handle authentication and other more juicy things.
 It takes time to fix all these issues unfortunately.

idk what to say, everyone did that since the beginning of times

I mean you can wrap a few things, if everyone did that all the time unhandled exceptions would be a thing at all. Some frameworks from what I've seen even encourage not handling errors in route handlers because those are handled automatically by the framework itself. I don't think being extremely defensive about that is what most people do at all, but maybe my perception is skewed.

you can supply your own onError handler to tinyhttp contructor in case you dislike the standard approach

That's what I'm doing at the moment, thanks for the suggestion.
To be clear I don't think this is a monumental issue, I think it's unlikely that any of the important dependencies I'm currently using is stupid enough to leak secrets like that, and even exposing some information about the code that runs on my server shouldn't be a problem, I'm much more happy about tinyhttp where a lot of the dependencies you wrote yourself than I am with express which imports the world along with it, still the less the better, maybe I can fork Polka and go with that or something.

good that it got settled down
thank you


Restore position of cursor after formatting

Having to move the cursor back from the end of the file everytime is very annoying.

I'd love to help, but that's not this package causing that. Should file an issue with atom-community/formatter.


Custom compiled streaming session disconnect: Only found one IP and Error, Multiple Threads in GPU

Component your question relates to

[XX ] Signalling server
[ ] Frontend library
[ ] Frontend UI library
[ X?] Matchmaker
[ ] SFU
[ ] This repo
[X? ] Other

Background
Our tiny ubuntu 20.04 Gnome X11 / A4000 Ampere V3 / UE5 server was 200 day long running, nice UPtime. 💯
It do serve on one IP .26 the web, and on second IP .77 it handle the Pixel Streaming.
Actually also both is t reach in browser. So it is up and still running.
! + We did changed NO script or game-script code ! (hopefully)
! - We do run any special construct, using a lot C++ and Visual Studio and also run any own compiler script.
NOW, "Why-Ever" it do in web not connect in the browser come Click to Start >> Disconnected: . :((
Normal it is only to open 5x terminal as non-root,
and to: start-signal, start-stream, start-game, NVTOP, HTOP.
// "Easy" that i can do as noob...
By starting it do talking about some lines.:
Only found one IP  = "suspect" but it say also "done anyway"... = perhaps there it do "split into double" ??
Error, Multiple Threads in GPU.  = Yes, in nvtop it looks also for me as "doubble-content" is running in it.
Question

How we can fix the (of course confuse fail construct),
Or can anyone help us to setup a "perfect" solution?

Additional context
We are only a tiny indie garage production, some digital nomads...
Our Avatar, won the second/third rank on a dance-competition,
before he learned walking.  ;))  (2/3* both have same amount of voting's)
Here is a view about what we do...
https://drive.google.com/drive/folders/1jIPxNCUI27wEGnk_n47_uc5ytrbFbbND

buschland.eu   web    go.buschland.eu  stream ... ! Sometimes the server is OFF but never long...

I'm not sure what the question is here, there seems to be a lot going on.
Are you able to break down exactly what the issue is here?

In short words, we are still by the way to repair it, and no one knows "how".  :((

I can't help you if I can't understand what the problem is. Can you describe what the problem is? Can you list the steps that I can take to reproduce the issue?

Good morning :)
ok, actually we are on a point, that both IP`s (web and game) do anyway do response.    "Step No1" :))
Now we try to understand where and how the "login & multiplayer" parts do working ...
I hope at the weekend we will find and understand it a bit...
Did you run on matrix?
/ With screen share and audio it is more "easy" to talk about complex chaos ...
I am user "b" in our 42.chat

Hi @buschmann, I'm closing this issue, if you still need help, please open a new issue and ensure to supply the following information, otherwise we can't assess the problem and help you.

What UE version and PS infra versions are you using?
What hardware/VM are you running your project on?
Are you using the default distribution of PS and its components? If not, what changes have you made?
When encountering the issue, please spell out step-by step exactly what you've done and where the issue occurs:
Is your project packaged for shipping/development? Does your project have any additional plugins and dependencies?
Can you succesfully stream it locally by launching the signalling server and connecting to your project on localhost?
Do you have the supplied signalling server/matchmaker/SFU running? Which component is exhibiting the issue?
If you have any crash logs/websocket information/ICE candidates exchange details, please share those and indicate when the issue occurs.

We unfortunately currently struggle to understand what the problem is and what component is exhibiting the problem.

Good morning ;)
What UE version and PS infra versions are you using?
.. It is UE5.1 and some tiny scripts.
What hardware/VM are you running your project on?
.. It is a dedicated root server, ubuntu 20.04, gnome, x11, with 128gb memory, A4000gpu.
Are you using the default distribution of PS and its components? If not, what changes have you made?
.. How can i check that ? I think that is all anyway hand build for the C++ multiplayer template...
When encountering the issue, please spell out step-by step exactly what you've done and where the issue occurs:
.. Easy to explain, 200 days before i did "start-signal, start-stream" and it was running fine.
We changed nothing in game code or scripts for starting it.
So i GUESS any server updates was fail or missing or a driver update delivered the problem.
Is your project packaged for shipping/development?
.. Oh yes, we have any external "compiler" running, also we use for game editing "run .sh as program" for editing, and most time
he worked in VSC not in UE editor.  BUT no one from us, have a clue how to "handle" that!
Does your project have any additional plugins and dependencies?
.. "Any", of course some tiny plugins i am sure are in it, but the most UE plugins and addons ad "whatever" do not run in
ubuntu. :((
But if we not did changed the compiled game code, i as noob GUESS, that is still fine... :)
Can you succesfully stream it locally by launching the signalling server and connecting to your project on localhost?
.. Last week a normal server admin and i try to reverse engineering the "construct" to understand a bit of it.
At the end we got a connect in browser, BUT only by IP with Port, and anyway the login user - multiplayer was still not running
/ connecting.
Then it was really late night, and the freelancer needs some sleep, and it looks as he sleep now since a week.
So NOW, i have no clue if i will do roll-back some files out of a old file backup, and IF yes, which one.. ?!? :((
I have some ubuntu sys backup files, also project files, but no "totally restore backup" .
Do you have the supplied signalling server/matchmaker/SFU running?
.. Of course he build also the matchmaker and Matrix login for it, it was running excellent.
..  so it do use our 42.chat system for SignUp process, on the signup end the user do landing in the matrix. and if a user do
LogIn from the game page, he do landing in the game..  :))
/// Jump to 10:10
Jump to 10:10
Which component is exhibiting the issue?
.. In the begin direct after the "crash" it was reporting in signaler one IP missing, and also a "multiple threads in GPU".
But that part is now running..
BUT i think, the server admin have now typed a new "start-script", perhaps that is now "not right way" as before...
If you have any crash logs/websocket information/ICE candidates exchange details, please share those and indicate when the issue occurs.
.. Logfiles and error logs we have "endless" :()
... It is as it is, we will need for future times at minimum one expert for c++ ue5 tech stuff in the team.
So if, IF the output is back and running, we will try to run a tiny "presale" to find some cash for more servers and more team.
Direct after we can start with founding a company and having then also hopefully a permanent stable team++ ... ;)

When encountering the issue, please spell out step-by step exactly what you've done and where the issue occurs:
.. Easy to explain, 200 days before i did "start-signal, start-stream" and it was running fine.
We changed nothing in game code or scripts for starting it.
So i GUESS any server updates was fail or missing or a driver update delivered the problem.

Is this the actual issue you are facing? Streaming was originally working some time ago and now it does not work?
You will need to provide us logs or error messages so we can triage the problem. Simply stating it does not work is not helpful.
Did you update the Pixel Streaming plugin, the Infra repo or the UE engine over that time? What were the versions that last worked, if you know?
When you try to open a stream now, what happens? Are there error messages in the UE logs? Are there error messages in the signalling server? Are there error messages in the browser or browser console?
If you can provide these details and show that the problem is within the Pixel Streaming ecosystem then we can reopen this issue. Currently this does not sound like a Pixel Streaming issue.


CommandBarFlyout causes crash with Windows.Ul.Xaml.LayoutCycleException

Describe the bug
Right-click Flyout menu using Command bar throw Windows.Ul.Xaml.LayoutCycleException & System.Exception on 2K monitor (2560x1440 & 125% Scale)

Steps to reproduce the bug

Have two monitors side by side. One 4K monitor at 3840x2160 - 150% scale, and one 2K monitor at 2560x1440 - 125% scale.

There are three scenarios:
Scenario 1:

Start the application on the 4K monitor, right-click (first Tab or Orange grid) to show the flyout menu, then left-click anywhere to hide the flyout menu. Observe there is no scroller on the flyout.

Next, move the application to the 2K monitor, and right-click (first Tab or Orange grid) to show the flyout menu, this time the flyout menu has a scroller.
Scroll the flyout menu. Application crashes with  Windows.Ul.Xaml.LayoutCycleException

Scenario 2:

Start the application on the 2K monitor, and right-click (first Tab or Orange grid) to show the flyout menu with the scroller. Scroll the menu.
Application crashes with
System.Exception: ClassFactory cannot supply requested class\r\n\r\nWindows.Ul.Xaml.Controls.Primitives.CommandBarFlyoutCommandBarTemplateSettings
And
Windows.Ul.Xaml.LayoutCycleException

Scenario 3:

Start the application on the 2K monitor, and right-click (first Tab or Orange grid) to show the flyout menu with the scroller, but don't scroll it. Left click to hide the menu.
Move the application to the 4K monitor, right-click to show the flyout menu, and then left-click to hide it.
Move the application back to the 2K monitor.
Right-click and scroll the flyout menu. Application crashes with  Windows.Ul.Xaml.LayoutCycleException

Expected behavior
The application shouldn't crash
Reproduce sample app:
LayoutCycleTestApp.zip
Screenshots
No response
NuGet package version
Microsoft.UI.Xaml 2.8.0
Windows app type

[X] UWP
[ ] Win32

Device form factor
Desktop
Windows version
Windows 11 (21H2): Build 22000
Additional context
No response

This issue hasn't been resolved

A fix for this issue has just been completed for WinAppSDK 1.5 (same fix as for #6218). This had already been partially improved in WinAppSDK and also partially fixed in Windows 11 for system XAML (/WinUI2).


use a random temp file name to store upload files

use a random temp file name to store upload files,  which prevent collisions in concurrent upload scenarios.

This PR is related to mine PR: https://github.com/openai/chatgpt-retrieval-plugin/pull/211, check also mine, please


Add internal API to get the service status

Add internal API to get the service status
Add an internal API to get the service status (starting, good or bad)
and a simple implementation for controller, broker and server. This can
be leveraged to determine the state of instances and expose the status
to deployment and monitoring infrastructures.

Current coverage is 64.68% (diff: 59.72%)

No coverage report found for master at 26785a5.

Powered by Codecov. Last update 26785a5...2316c28


Add WindowedvalueParam option to DoFns.

This is useful when one wants to capture and preserve all the windowing information for later use (and is both more convenient and less error-prone than gathering the timestamp, windows, and pane info separately).
New values with the same windowing value can be constructed via WindowedValue.with_value(...) and emitted asynchronously (e.g. after batching or in finish_bundle).

Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:

[ ] Mention the appropriate issue in your description (for example: addresses #123), if applicable. This will automatically add a link to the pull request in the issue. If you would like the issue to automatically close on merging the pull request, comment fixes #<ISSUE NUMBER> instead.
[ ] Update CHANGES.md with noteworthy changes.
[ ] If this contribution is large, please file an Apache Individual Contributor License Agreement.

See the Contributor Guide for more tips on how to make review process smoother.
To check the build health, please visit https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md
GitHub Actions Tests Status (on master branch)

See CI.md for more information about GitHub Actions CI or the workflows README to see a list of phrases to trigger workflows.

R: @ganesh4991


Best practive / help

Not really an issue but more help. I'm a bit confused.
db.rel.save('author', {
  name: 'George R. R. Martin', id: 1, books: [6, 7]
}).then(function () {
  return db.rel.save('book', { title: 'A Game of Thrones', id: 6, author: 1});
}).then(function () {
  return db.rel.save('book', {title: 'The Hedge Knight', id: 7, author: 1});
}).catch(console.log.bind(console));

what I don't understand in this code, you save a new author, and also add the new book foreignkeys. But in real life you would not know these keys before you created the book records. The author foreign key makes sense in the book records. So why the book id's in the 'books' array?

@fransyozef With the way that CouchDB/PouchDB, works there are no auto-incrementing IDs like a SQL database. In PouchDB, you can opt to have an _id generated for you(a uuid I believe). This is how you would have the ID ahead of time. And since uuid's are pretty much guaranteed to to be unique you shouldn't have to worry.
You can choose to have your HasMany relationships not represented by an array of IDs on the parent type. Take a look at this section of the README.md: https://github.com/pouchdb-community/relational-pouch#dont-save-hasmany. For this case you would first create the author and then create each book utilizing the id from the author you created.
If you would like I can come up with a code sample for you. The code sample you are referring to is following a pattern where child books that belong to the author are having their IDs stored on the author, whichh is not required. Just simply an example of how relational-pouch can be used.


Support to lock/forbid a stopped container to be deleted.

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
No.
Describe the solution you'd like
A clear and concise description of what you want to happen.
I haven't been able to find a specific feature to do that, it is possible to it but not directly as a feature itself:

I want to be able to select a specific stopped container and set it to not be able to be deleted.
Of course I can just be careful and make sure to not delete the container I want when selecting to delete all other, but I have seen that it always ends up being deleted by mistake.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Doing it manually only.
Additional context
Add any other context or screenshots about the feature request here.

Context on why this would be helpful:
Sometimes I have a specific container running a database on it, with some data set up and loaded, the process of loading that data is hard and boring, so I try to not exclude that container so I don't have to do it over again.
The problem comes when I run a bunch of other containers and want to delete them all from the UI by selecting all at once, but then I have to deselect the one I want to keep, as imagined every now and then I delete it by mistake.
I wanted to be able to select an option somehow that this container would never be deleted, kind of like it happens with the portrainer container itself.

Closing as duplicate of #6860


Gitlab CI merge request service

This is a first implementation of exposed entrypoint to build gitlab ci service to integrate PHPCI as CI server.
Actually I have JSON conversion into Gitlab class, maybe will be better have a more generic helper to allow all type of build to be converted on JSON. Before I implemented it on controller and after moved on PHPCI\Model\Build but I'm not sure is a good place to store this conversion. Maybe a new helper class? Any suggestion?
I think is required a token to allow information reading without expose project information as public.
Test are required, please do not merge, just use this MR as support request :smile:.
Next steps:

[ ] define better solution to convert build to JSON
[x] introduce a validation token to allow non public project to be read
[ ] add tests
[x] implement phpci_ci_service similar to gitlab_ci_service

@mavimo Did you have a way to finish this feature? Maybe it is an option to create also a pull request to gitlab if this is finished.

@tvbeek I changed approach since gitlab PR are not accepted since there are a lot of push on it.. I will create a controller that have the same fingerprint of Gitlab CI, and use the same service definition. I will send it as contrib ASAP.


feat(riak): add riak chart

Note that users still need to run a few commands as per https://github.com/deis/riak#usage, but if HA isn't a concern then I can strip away everything but the pod manifest if that makes sense.

@bacongobbler let's change the path from riak to riak-cluster for convention.

done :)

hold off on merging this one; I'm going to provide both worlds:

HA Riak (current work)
standalone Riak pod (same as other examples)

Dude, you are seriously ripping it up with these! Good example of using the provider label.

I dropped the clustered riak chart for now while trying to debug what's wrong with it so we can get this one out the door.

Tested with helm 0.1.0, everything looks good and I can curl the server 8098 endpoint inside the cluster. kubectl logs riak doesn't show anything, but maybe it wouldn't? Looks good to me.

Yeah that's something I need to fix up at some point. By default riak logs to a file inside the container. deis/riak was inspired by https://github.com/hectcastro/docker-riak which logs to /var/log/riak. I just need to tweak a few things inside https://github.com/deis/riak/blob/master/rootfs/bin/boot to start riak with logs in the foreground, though most of my attempts to do so have failed since I have to background the process.
One way is to use the same technique we use in deis/router but I'd rather do something more native instead of a goroutine piping logs to stdout/stderr.


"Ninja is required to load c++ extensions" && "fail to build pysdf"

My enviroment: Windows11, torch-1.11.0, cuda-11.3, cudnn-8200
command: python main_nerf.py data/fox --workspace trial_nerf
I've installed Ninja. Before this problem I had the same problem as #160 and I solved it by installing Microsoft VS2022 (but the installation path was in E:, so I changed the default path in find_cl_path()), but I'm not sure this solution is reasonable. After that I ran into this problem.

By the way, I can't build pysdf successfully, the path of MVS2022 appears in the error message, I don't know why this is related to MVS, maybe I should install MVS in the default path?

Thanks a lot !!!!

When building pysdf, i met this error as well. It is because somehow you are using HostX86\\x64\\cl.exe. But what you should use is HostX64\\x64\\cl.exe.
Please try using x64 Native Tools for VS 2022 instead of Developer Command Prompt for VS 2022. This is what I did to resolve this.


Markdown preview doesn't resize properly on zoom (Ctrl++)

VSCode Version: 1.9.0-insider ee9d91c05fa571de56c41383cceee30b05b0a2f6
OS Version: macOS Sierra 10.12.2

This also happens on vscode 1.8
Steps to Reproduce:

Open markdown preview
Press Ctrl++ to zoom in

Its a bit hard to see but the the preview content isn't filling the whole area -- there is a big empty space on both the right and bottom.

Thanks. Closing as a duplicate of #5745 since the MD preview uses a webview


Update LocalRest to get range error fix

@Geod24 I am not fan of this manually maintained submodules readme. What do we need it for?
And the commit date for the previous localrest update was wrong (July 22 instead of July 21).

@Geod24 I am not fan of this manually maintained submodules readme. What do we need it for?

It was just to have an overview, especially the repository owned. But now that we have many forks, the point is almost moot.

And the commit date for the previous localrest update was wrong (July 22 instead of July 21).

Looks like I used the date at which we updated Agora instead of the commit date.


how do i pass a user name and password as a secret for a external postgres database?

How do i store an external database connection details as a secret for data lore? I want to store this workflow as a helm chart in gitops and storing my username and paswords is not attractive to me.

Hello @weiyentan you can use databaseSecret parameter with existing secret to store the password https://github.com/JetBrains/datalore-configs/blob/2023.3/charts/datalore/values.yaml#L92
databaseSecret:
  create: false
  name: <secret-name>
  key: ROOT_PASSWORD

thank you. what about settting the username?

Sorted this. For posterity it is in the db_user and dataenv section of the values.yaml


Propagate Collection Reset to the inverse of a m2m Relation

Is your feature request related to a problem? Please describe.
Currently diffing only happens on the owning side of a M2M relation, however there is some nuance here - altering the references on the inverse side works because the change is propagated up to the owning side, this does not work for resetting the collection i.e. assigning a empty array to the inverse side.
Describe the solution you'd like
It would be good if, when resetting a collection on the inverse, that were also propagated to the owning side.

Closing as this should be working fine with v5 (tried to do removeAll() on an inverse side and it correctly removed the items from owner too).


Hide help button on pages with drift survey

This change is

http://cockroach-docs-review.s3-website-us-east-1.amazonaws.com/40a7d80d361962115408eb16a4b28d55e45e6d09/


Added screenshots to readme

Added screen shots to readme file

@manjunathc23  please check if the screen shots are as we required.

@muditpant13 : Can you please clear the notifications and generate device art using https://developer.android.com/distribute/tools/promote/device-art.html

@manjunathc23 done please check. added wrong screen shots before. :)

This was rebased and merged into master.


Method 'findKeysByPatternAsync' always get all the keys

For this code
“RBatch batch = client.createBatch();
Future<Collection> future = batch.getKeys().findKeysByPatternAsync(PATTERN_PREFIX + "*");"
it always return all matching keys?
In case the number of keys is very large , I need to get keys in batches. There seems to be no way out.

RKeys.findKeysByPatternAsync method is deprecated. Please use RKeys.getKeysByPattern instead it allows to specify batch size.

Although method 'RKeys.getKeysByPattern'  is to get key in batches，But eventually it will put all the keys in  the memory.I mean, is there a method like the cursor  of redis-client?

@handjgit
No, it doesn't put all the keys in memory. it uses Redis cursor command

So, if a value of 500 is assigned to the 'count' parameter,It only returns 500 keys？but,how can I get the next 500 matching keys? and then next next 500 matching keys? Until I get all the keys.

it will return all keys and request to redis for next 500 keys during iteration once you traversed previous values.

Oh!


LXC Init with Debian Bullseye image hangs - locked?

LXC v4.16 on Ubuntu Focal
Encountered this on a system today, never seen this before:
# lxc init images:debian/bullseye foo
Creating foo

Hangs forever, while LXC monitor says:
location: none
metadata:
  context: {}
  level: dbug
  message: Acquiring lock for image download of "93a8f44df60764e57e0d87d54b06ed2a444304610bf045bf3e9072089911d590"
timestamp: "2022-04-19T15:51:40.698513185+02:00"
type: logging

And does not proceed. So, something has that image locked? I tried deleting the image with lxc image delete - this did not improve the situation on subesequent tries.
I made sure the server can reach images.linuxcontainers.org - I also checked to see if any processes were running referencing this image:
# ps aux | grep debian
But no hits.
I also tried other images from that remote, and they work, e.g.:
# lxc init images:almalinux/8 foo
Creating foo
root@tora:/home/master# lxc delete foo
root@tora:/home/master# lxc image delete f2725d46b3cd
root@tora:/home/master# lxc init images:almalinux/8 foo
Creating foo
root@tora:/home/master#

So it's just this one image LXD is having issues with. Not sure what this is or how to recover.

Can you try reloading LXD as I just tried that here using lxc init images:debian/bullseye foo and it completed fine.
It suggests perhaps there is an ongoing download of the image that has got stuck, perhaps due to network issues.

@tomponline Yes this works on other installs, so it's just hanging on this system for some reason.
How should I reload LXD? Will this bring down my containers? If so, I'll need to do this in a maintenance window. Please advise...

Normal LXD reload, no it won't bring down your containers.
sudo systemctl reload snap.lxd.daemon

Ouch well that wasn't completely safe to do, as I have a lot of containers on there so the procedure has taken some time and is now - seemingly - hanging. During which LXD is inoperational so our systems can no longer interact with containers via. LXD - which is bad.
It looks to be hanging here:
location: none
metadata:
  context:
    socket: /var/snap/lxd/common/lxd/unix.socket
  level: info
  message: ' - closing socket'
timestamp: "2022-04-19T16:10:52.155257014+02:00"
type: logging

So yeah... Anyway should I just wait and try to mitigate whatever issues turn up while this runs to completion, eventually, hopefully, or should I press the big red reboot button on this system? :)
I'll be sure to post as soon as something, hopefully, changes.

You probably have an ongoing operation (exec or console) which we are waiting to finish before reloading. You can configure the max wait time.

@tomponline I am not sure I understand from that how I resolve the current situation? :) I have no idea which operation it is, how do I track it down and kill it to unstick the system?
I'd love to not have to reboot as that's always a bit painful to do.

OK 25 minutes later after I started the reload I still have a hanging system so I am rebooting at this point.
Some hints on where and how to set max wait times, so I hopefully won't encounter this pickle again, would be appreciated :)
Thanks for your help today Tom

Sidenote: A reboot unstuck the system and all is well now - I did an upgrade to 5.0 whilst I was at it, why not.

You could have probably just killed the lxd process rather than rebooting, as that wouldn't have restarted your instances.
I was thinking of core.shutdown_timeout which defaults to 5 minutes though so not that.
https://linuxcontainers.org/lxd/docs/master/server/

@tomponline Got it. Thank you for your assistance today.
Although ... If I may be so bold as to suggest that it may be a good idea to implement some better discoverability on what causes locks like these, or implement some (generous, depends on what it is I suppose) timeouts on locks as to avoid these scenarios.

Go locks don't have timeouts. But it sounds to me like that wasn't the issue, but rather than the operation happening inside the lock never finished (it is that which should have the timeout rather than the lock). If you see the issue again or can provide logs of what was happening when the problem occurred (perhaps it was downloading the image and got stuck somehow - although we do have timeouts on network operations) then we can try and resolve this. We don't yet know why LXD didn't stop.

some better discoverability on what causes locks like these

If it happens again you can enable pprof and get a stack trace of the running threads using:
lxc config set core.debug_address <IP_ADDRESS>:8444
curl http://<IP_ADDRESS>:8444/debug/pprof/goroutine?debug=2

Thanks Tom - I will try to remember these steps if this ever happens again. Probably it wont but who knows.

I'm reopening this issue due to the timeout revert being applied in https://github.com/lxc/lxd/pull/10407

I've observed something similar where if a network connection is stalled during image download, the connection can hang for a long time, keeping the image lock open. We need to improve stalled connection timeouts in the client/server so that a broken connection is closed sooner.


Fix v2.0 Unit Tests

Which package has an issue?
@yamada-ui/react
Package Version
2.0
Description
This PR aims to refactor these tests to ensure that the applied CSS styles are correctly validated.
Link to Reproduction
No response
Steps to Reproduce

Go to '...'
Click on '...'
Scroll down to '...'
See error

Browser
None
Operating System

[ ] macOS
[ ] Windows
[ ] Linux
[ ] iPadOS
[ ] iOS
[ ] Android

Do you know how to fix the issue?
Yes
Are you willing to participate in fixing this issue and create a pull request with the fix?
Yes
Additional Information
No response

I'll try it.

Fixed #2284


Can't read properties of event.details (sent from JS)

In the JS demo event.details looks like:
Object {keyboardEvent: KeyboardEvent}
> keyboardEvent: KeyboardEvent
v __proto__: Object
  combo: "pageup"
  event: "keydown"
  key: "pageup"
  __proto__: Object

in Dart
v {keyboardEvent: Instance of 'KeyboardEvent'}
  > [[class]]: _InternalLinkedHashMap

sent from https://github.com/PolymerElements/iron-a11y-keys/blob/master/demo/x-key-aware.html#L49
I can access event.detail['keyboardEvent'] but event.detail['combo'] doesn't work in Dart (works fine in the JS example)
Any idea how to get access to the combo item?

I have a feeling it might just need to be updated, also if the detail object is actually another event and they set custom properties on it from JS then you would need to do something like:
new JsObject.fromBrowserObject(e.detail['keyboardEvent'].original)['combo']
We could possibly automate this in the CustomEventWrapper object though (it is already abstracting away some of the event.detail madness from you)

I tried that.
combo isn't a property on KeyboardEvent but another item in the map (sibling to keyboardEvent) but added to __proto__ (my interpretation from my limited JS knowledge) and not accessible from the Dart side.
in JS event.detail.combo returns pageup. In Dart event.detail['combo'] returns null`.

Ok, so this should work: convertToJs(event.detail)['combo'] (jsValue instead of convertToJs if you are on the 0.2.0-dev branch of polymer_interop). Basically convertToJs gives you the original JsObject that the map was created from.
Long story short it looks like they are hot swapping the prototype of the object without actually creating a constructor, and that breaks some assumptions in convertToDart so the dart map we create doesn't contain things from the prototype.

Edit: they aren't hot swapping they are creating it with Object.create(proto). When you do that the constructor is still Object, so we think its a normal object and go ahead and create a map out of it. We should be checking that the __proto__ is equal to Object.prototype instead.

should be fixed now (although not verified)

Yup, works fine :)


Multiple file elements in a single form is not working

When we add two file type in same form then filestyle plugin is breaking. First file element works fine as expected, however choosing a file from second element is updating first file element's textbox.

Push example in jsfindle


Missing newline

This simple program
use "assert"

actor Main
  new create(env: Env) =>
    env.out.print("foo")

    let i: I32 = 0
    try
      Fact(i > 0, "i > 0 failed")
    end

    env.out.print("bar")

sometimes outputs
fooi > 0 failed
bar

instead of
i > 0 failed
foo
bar

Flushing stderr with @fflush[I32](...) before printing to it with @fprintf[I32](...) in https://github.com/ponylang/ponyc/blob/master/packages/assert/assert.pony#L27 resolves this issue, but I'm not sure if that's the best solution.

Fact calls @fprintf synchronously, whereas Stdout.print is asynchronous. So there is no ordering guarantee between these. If you run your program using a single ponythread (--ponythreads=1) you should always get:
i > 0 failed
foo
bar

With more than one thread, the ordering is non-deterministic, including possibly getting interleaved output, depending on the FILE semantics of your local libc.
I think this particular interleaving may be happening on linux for you? If so, then could you try in stdfd.c line 775 changing:
  fwrite_unlocked(buffer, len, 1, fp);

to:
  fwrite(buffer, len, 1, fp);

If that stops the interleaving, we should discuss if we should stop using the unlocked versions of FILE calls or not.

I'm on OS X 10.11.6.

@toblux what version are you using of Pony?

@SeanTAllen I've tried both the latest release on Homebrew
$ ponyc --version
0.2.1-996-g5f061fa [release]

and the current master branch.

I think the issue is that writing to stderr and stdout on OSX doesn't guarantee atomicity between the streams.
So I think actually @toblux your initial idea is fine - fflush of stderr when writing synchronously in Assert. Are you up for filing a PR?

@toblux newline is ascii character 10, carriage return is 13.
so if you have a "10" for your U* in your Array[U8], that's a newline.

The problem with
be print(data: ByteSeq) =>
  match data
  | let s: String => _write(s.add("\n"))
  else
    _write(data)
    _write("\n")
  end

is that is has a large performance impact that we wouldn't want to pay.
This would result in additional branching having to be done as well as an object allocation inside add:
  fun add(that: String box): String =>
    """
    Return a string that is a concatenation of this and that.
    """
    let len = _size + that._size
    let s = recover String(len) end
    (consume s)._append(this)._append(that)

@toblux you are exactly right, thank you!
We need to do two things:

Clean up stdfd.c to no longer deal with stripping ANSI codes. It still needs to issue Console commands on Windows.
Add a version of pony_os_std_write that inserts the newline in a single FILE* operation (i.e. fprintf).

I'll assign myself to this if no one else is working on it.


support user incremental predicates on merge

Describe the feature
Users should be able to supply incremental models with arbitrary predicates during the merge step to prevent unnecessary table scan for massive data sets.
Describe alternatives you've considered
None
Additional context
See:

Core Issue 5680
Core Issue 5680
Core PR 5702

Who will this benefit?
users with extremely large datasets who want to limit the scan of their merge operations on incremental models!
Are you interested in contributing this feature?
Yes

@ueshin @superdupershant seems like a reasonable ask since it's supported in other DWs.


Improve BulkSplitOptimizationIT

Partially addresses #5123
The most important change in this PR is just to bump the timeout from 2 to 5 minutes since the test often times out
I also...

added logging to make it easier to tell how far the test got and where it times out at in the future
moved the creation of the rfiles to the before block
created the test table using NewTableConfiguration and made the initial availability HOSTED to speed things up slightly

With the new logging you added do you know where the most time is being spent in the test?

I added some timing logging to the test to find out. Here is what the logs show:
Took 31778 ms to stop all tservers
Took 3 ms to start all tservers
Generated 100 files in 403 ms
Created table in 23334 ms
Imported into table in 601 ms
Took 3031 ms for split count to reach expected range


Cross builds on macOS runners cannot find Cargo.toml?

Do the checklist before filing an issue:

[x] Is this related to the actions-rs Actions?
If you think it's a problem related to Github Actions in general, use GitHub Community forum instead: https://github.community
[x] You've read the Contributing section about bugs reporting: https://github.com/actions-rs/.github/blob/master/CONTRIBUTING.md#reporting-bugs
[x] Is this something you can debug and fix? Send a pull request! Bug fixes and documentation fixes are welcome.

Description
Ubuntu builds succeed, but the same step definition for runs-on: macOS-latest is unable to find cargo?:
Run<EMAIL_ADDRESS>Install cross
cross build --target x86_64-unknown-linux-musl --all-features --verbose
+ "cargo" "build" "--target" "x86_64-unknown-linux-musl" "--all-features" "--verbose"
error: could not find `Cargo.toml` in `/Users/runner/work/rust-htslib/rust-htslib` or any parent directory
Error: The process 'cross' failed with exit code 101

Workflow code

  Testing-OSX:
    needs: Formatting
    runs-on: macOS-latest
    steps:
      - name: Test musl build with all features and debug symbols (non --release) on OSX
        uses<EMAIL_ADDRESS>        with:
          use-cross: true
          command: build
          args: --target x86_64-unknown-linux-musl --all-features --verbose

That was not the underlying issue, sorry for the noise.


ADR: Use meta.yaml to track feedstock metadata

ping @pangeo-forge/dev-team for review

I merged #12 and reformatted this as an ADR. I used the linked adr tools CLI like this
adr new Use meta.yaml to track feedstock metadata

to generate the ADR. This brought up some inconsistencies with the existing ADR from #12.

The adr tools CLI created the new ADR in doc/adr, but the earlier ADR is in docs/hdr.
The adr tools CLI generated a number (001) for this ADR.

I would propose to harmonize these by moving the other ADR to doc/adr and numbering it 001 (this one becomes 002).

@danielballan , do you know where a concise and authoritative description of the entrypoint syntax can be found? I am hoping for something without reference to console_script

I would look to https://docs.python.org/3/library/importlib.metadata.html and the source backing it.


allow for custom repr function + bump version

Pull Request Test Coverage Report for Build<PHONE_NUMBER>

13 of 14 (92.86%)  changed or added relevant lines in 4 files are covered.
2 unchanged lines in 1 file lost coverage.
Overall coverage decreased (-0.5%) to 99.514%

Changes Missing Coverage
Covered Lines
Changed/Added Lines
%

tests/test_u_core.py
8
9
88.89%

Files with Coverage Reduction
New Missed Lines
%

zninit/descriptor/init.py
2
97.8%

Totals

Change from base Build<PHONE_NUMBER>:
-0.5%

Covered Lines:
614

Relevant Lines:
617

💛  - Coveralls


keep cars in position when demoed instead of 0, 0, -50000 from simulator

changed the car position to stay where it is when demoed. This has been implemented for months in mtheall python bindings, but this is necessary for the rust rocketsim-rs to pick it up. It's running fine and built fine on my machine.

(This was fixed in a previous update)


Sometimes table visualization columns don't auto-size correctly when visualization is initially opened

Discord username
No response
What type of issue is this?
Intermittent – Occurring irregularly
Is this issue blocking you from using Enso?

[ ] Yes, I can't use Enso because of this issue.

Is this a regression?

[ ] Yes, previous version of Enso did not have this issue.

What issue are you facing?
Sometimes when I initially open a Table visualization for a node, not all of the columns auto-size to fit their content:

If I drag a corner of the visualization to resize it, the columns resize to their content as soon as I have changed the visualization size at all.
Expected behaviour
Columns auto-sizing should not change completely when a small visualization resize occurs; I think the intended behavior is for them always to be sized to their content.
How we can reproduce it?

Open a table visualization.
Often, but not always the bug is apparent.

I think this has been occurring for a long time (on the scale of weeks).
Screenshots or screencasts
No response
Logs
No response
Enso Version
develop (fd972f8)
Browser or standalone distribution
Standalone distribution (local project)
Browser Version or standalone distribution
standalone
Operating System
Linux
Operating System Version
No response
Hardware you are using
No response

This should be tested with GUI2, both with regular opening and fullscreen opening on a newly opened project (shift+space)
However, I think the shortcut for fullscreen vis might have been (unintentionally?) removed. @Frizi can you confirm? I think it might have been one of your changes, so I'm just confirming whether that was intentionally removed, or whether we should add new bindings to the shortcut registry

Upon some investigation: it seems like we do have bindings for opening a visualization, but none for opening a fullscreen visualization:
https://github.com/enso-org/enso/blob/cd84ac16ce4c98f22d0eda8e65a5ddb27b5eb1d5/app/gui2/src/bindings.ts#L24


cleanup use test-discovery main file name

motivation: small follow up cleanup to #3992 which consolidates the use of a share definition for the test discovery main file name
changes: use the shared definition for the main file name used for test discovery everywhere

@swift-ci please smoke test


[FLOC-3895] Count timeout for effect retry from the first effect failure

Fixes https://clusterhq.atlassian.net/browse/FLOC-3895

LGTM. Merge when tests pass.

Thanks.  Only main multijob failed, and failed because of a known problem tracked elsewhere.  Merging.


We are using preact-cli

Thought it would be better to list all projects using preact-cli for their applications in production, which can be added to the wiki page.

One I found while crawling the web:  it looks like pretty much the entire gatorade.com site is built with Preact CLI!

Consent for using their site name mmust be thought upon.............

Yup! That's why it hasn't been listed. Their use of the CLI is public knowledge though, I was able to detect it using BigQuery.

Maybe instead of pointing to a specific Homepage / Product, offering companies to highlight that they are using it ? We are using it for two internal applications and I know of some more teams :-)

@fokusferit i guess just organization name should be fine

Yes - organization names are ideal actually - I think the goal here is to collect a list of logos we can then show on the homepage once it's created.


Theme support

Are there plans to add themes to Portainer? I personally like dark themes, as I know many others do as well. It'd be great if we could choose themes from a list, as well as add our own customized ones.
For example, I've been creating a dark blue theme that looks great (It's about 99.9% done), but have to use the browser extension "Stylus" to use the style, and while I like it for designing themes, ultimately I don't like having to use an extension for themes.
Here's the theme I've created so far (the screenshots don't do justice of actually using it page by page), It'd be nice to have it as a choice to select from right from within Portainer itself.:

@STaRDoGG there are no plans to support themes in Portainer at the moment but we're keen to support this.
Can you give us a bit more details on how you created that theme and how could we potentially integrate it?

@deviantony I use Stylus to style pages with my own customizations after editing them via the Chrome inspector.
If you're not familiar with it, basically, it is just an extension that loads it's own .css sheet (with your own changes in it) after the page is loaded, so it 'overwrites' the CSS that is already there with the page.
I'd try contributing wit a PR myself, but I'm not familiar with portainer's code, and it looks like it would take some time analyzing before I got the 'flow' down, and I just have too many other projects going on atm to get into all of that.
I was thinking just an area in the settings page, with a drop-down-combobox to select the theme to use, and them it would load up that stylesheet (for any styles that come with portainer), and perhaps a blank textarea that a user could paste any CSS tweaks/code they want into, and whatever is in that box would just be loaded 'last' so that it takes precedence over any CSS already loaded. That way they'd be able to add their own styles to portainer itself on their own machine, and it would still be used throughout the app for other users as well, rather than how Stylus only changes for whoever has the extension and style installed.

@STaRDoGG can you join us on slack to discuss this?

@deviantony Unfortunately I can't right now, I have to go out and shovel the driveway before the family gets home, lol, we're in the middle of an early blizzard here in chicago. But I can probably do it at another time if you're interested.

@STaRDoGG sure thing, feel free to reach out to me on slack for a more direct discussion. In the meantime we can also continue the discussion here.
I've never used Stylus before, it's pretty cool.
My opinion regarding this feature addition in Portainer would be to have something simple, just a dropdown or a way to select a theme in the Portainer setting (no custom css box).
It would be very nice to have a user guide on how to produce a theme though. Maybe we could leverage Stylus for that. Do you know if Stylus produces a custom CSS file that we can bundle with the app?
cc @xAt0mZ for more input on how we can dynamically load styles.

Here's the current CSS I have (again, it's not complete, but close) if you want to see how it looks on your own portainer instance.
Just add it to Stylus:
/* Clean dark portainer UI

TODO::
- Templates Page: Search Bar needs work. Particularly the colors when clicked in/on.
- Events Page: Pagination.
- Users Page: The white things on the input fields are too bright.
- Exec Console needs work. (when clicking it's icon on a container in the list)
- Columns & Settings Icons, need work.
- Finish the Login box. 5px bord-rad, input backgrounds, and icon backgrounds.
- Swap Button background colors(?). i.e. the "text/tree" buttons on the Inspect pages)
----------------------------------------------- */
@import url('https://fonts.googleapis.com/css?family=Rubik&display=swap');

body {
    background: #292D3E;
    font-family: Rubik;
    color: #b2bfdc !important;
}

/* Login Panel: Begin */
.panel-body {
    background-color:#232f48;
    border: 1px solid #1b1e2b
}

.panel-default {
    border-color: #2d3e63;
}

.panel {
    background-color: #2d3e63;
}
/* End*/

/* Sidebar: Begin */
.sidebar-header a {
    color: #D8DEE9;
}

ul.sidebar .sidebar-list a.active {
    color: #E5E9F0;
    border-left: 3px solid #E5E9F0;
    background: #2d3e63;
}

ul.sidebar .sidebar-title.endpoint-name {
    color: #EBCB8B;
}

ul.sidebar .sidebar-title {
    border-bottom: 1px solid #292d3e;
    margin: 1.1em 0 0 0;
}

ul.sidebar .sidebar-list a:hover {
    color: #E5E9F0;
    border-left: 3px solid #D08770;
}
/* End */

/* Buttons: Begin */
.btn-primary {
    color: #D8DEE9;
    background-color: #286090;
    border-color: #204d74;
}

.btn-primary:hover {
    color: #D8DEE9;
    background-color: #5E81AC;
    border-color: #81A1C1;
}

.btn-primary.active.focus, .btn-primary.active:focus, .btn-primary.active:hover, .btn-primary:active.focus, .btn-primary:active:focus, .btn-primary:active:hover, .open>.dropdown-toggle.btn-primary.focus, .open>.dropdown-toggle.btn-primary:focus, .open>.dropdown-toggle.btn-primary:hover {
    color: #E5E9F0;
    background-color: #204d74;
    border-color: #122b40;
}

/* Search Box 'Button': Begin */
.btn-default:hover {
    color: #30426a;
    background-color: #1b1e2b;
}
/* End */

/* Stacks page, Tab: Begin */
.nav-tabs>li.active>a, .nav-tabs>li.active>a:focus, .nav-tabs>li.active>a:hover {
    color: #E5E9F0;
    background-color: #1b1e2b;
    border: 1px solid #30426a;
    border-bottom-color: #30426a;
}

.nav-tabs {border-bottom: 1px solid #30426a;}
/* End */

.row.header {
    height: 60px;
    background: #1B1E2B;
    margin-bottom: 15px;
}

.datatable .footer {
    background-color: #1B1E2B;
    border-radius: 0 0 5px 5px;
    color: #D8DEE9;
}

.datatable .actionBar, .datatable .toolBar {
    color: #D8DEE9;
    padding: 10px;
}

.datatable .toolBar {
    background-color: #1B1E2B;
    border-radius: 5px 5px 0 0;
}

.datatable .searchBar {
    border-top: 1px dashed #1b1e2b;
    border-bottom: 1px dashed #1b1e2b;
    background-color: #252a3c;
}

a {
    color: #81A1C1;
    text-decoration: none;
}

a:hover, a:focus, u, .btn:hover {
    color: #ECEFF4;
    text-decoration: none;
}

/* 1 Place this is used is the search bar 'button' on the Templates page ...*/
.form-control, output {
    color: #5E81AC;
    border: 1px solid #232f48 !important;
    border-radius: 5px;
}

.widget {
    -webkit-box-shadow: 0 1px 1px rgba(0,0,0,.05);
    box-shadow: 0 1px 1px rgba(0,0,0,.05);
    background: #232f48;
    border: 1px solid #1b1e2b;
    border-radius: 5px;
    /*border-color: #e9e9e9;*/
}

.widget .widget-header {
    color: #b2bfdc;
    background-color: #232f48;
    padding: 10px 15px;
    border-bottom: 1px solid #e9e9e9;
    line-height: 30px;
}

/* Text in table headers */
.widget .widget-body table thead * {color: #ECEFF4;}

/* TODO: Duped the above selector, but there are a cpl changes here.
   Designed the above on the Home tab, then the below on the Dashboard tab,
   and haven't throughougly gone through testing what it all affects. */
.widget .widget-header {
    background-color: #30426a;
    border-bottom: 1px solid #292d3e;
    border-radius: 5px 5px 0 0;
}

.text-muted {color: #bf7449;}

.widget .widget-body table thead {
    /* background: #232f48; */
    background: #1b1e2b;
}

.blocklist-item {
    border: 1px solid #1b1e2b;
    margin: 10px 0;
    -webkit-box-shadow: unset;
    box-shadow: unset;
}

/* Hovered Items in Block Lists, i.e. Endpoints List */
.blocklist-item--selected, .blocklist-item:hover {
    background-color: #2d3e63;
    color: #E5E9F0;
}

.datatable .searchIcon {
    color: #EBCB8B;
    margin-right: 5px;
}

/* Labels & Such: Begin */
.label {color: #ECEFF4;}
.label-success {background-color: #A3BE8C;}
.label-warning {background-color: #EBCB8B;}

/* Special floating for the label on the Volumes & Images pages, for aethestics */
span.label.label-warning.image-tag.ng-scope {float: right;}

.label-danger, .btn-danger {background-color: #BF616A;}
.label-primary, .btn-primary {background-color: #5E81AC;}
.fa.green-icon {color: #A3BE8C;}
.fa.red-icon, .text-danger {color: #BF616A;}
.fa.orange-icon, .text-warning {color: #D08770;}

/* "Filter" text on colunmn headers */
.widget .widget-body table thead th .table-filter {color: #EBCB8B;}

/* i.e. The circular icons on the Dashboard page */
.blue {background: #1b1e2b!important;}
/* End */

.form-control {
    width: 100%;
    height: 34px;
    padding: 6px 12px;
    background-color: #1B1E2B;
    background-image: none;
    border: 1px solid #ccc; /* hmmmm .... */
    border-radius: 4px;
    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
    box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
    -webkit-transition: border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
    transition: border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
    transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
    transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
}

.form-control, output {
    display: block;
    font-size: 14px;
    line-height: 1.42857143;
    /* color: #337ab7; */
    color: #5e81ac;
}

.table .table {background-color: rgba(0,0,0,.25);}

.table>tbody>tr>td, .table>tbody>tr>th, .table>tfoot>tr>td, .table>tfoot>tr>th, .table>thead>tr>td, .table>thead>tr>th {border-top: 1px solid #30426a;}
.table>thead>tr>th {border-bottom: 2px solid #1b1e2b;}

/* Background hover color for table items */
.table-hover>tbody>tr:hover, .table>tbody>tr.active>td, .table>tbody>tr.active>th, .table>tbody>tr>td.active, .table>tbody>tr>th.active, .table>tfoot>tr.active>td, .table>tfoot>tr.active>th, .table>tfoot>tr>td.active, .table>tfoot>tr>th.active, .table>thead>tr.active>td, .table>thead>tr.active>th, .table>thead>tr>td.active, .table>thead>tr>th.active {
    background-color: #2d3e63;
}

/* Table item borders */
.table-bordered, .table-bordered>tbody>tr>td, .table-bordered>tbody>tr>th, .table-bordered>tfoot>tr>td, .table-bordered>tfoot>tr>th, .table-bordered>thead>tr>td, .table-bordered>thead>tr>th {
    border: 1px solid #232f48;
}

.form-section-title {
    color: unset;
    border-bottom: 1px solid #2d3e63;
    margin-top: unset;
    padding-bottom: 1em;
}

#view > information-panel > div > div > rd-widget > div > rd-widget-body > div > div > div.form-group.ng-scope > ng-transclude > span,
#view > div:nth-child(3) > div > rd-widget > div > rd-widget-body > div > div > form > div:nth-child(2) > div > span {color: #D8DEE9;}

json-tree {color: unset;}

/* Colored text on the Roles page.*/
.portainer-disabled-datatable {color: #1b1e2b;}

/* Sliders/Switches: Begin */
.bootbox-form .checkbox i, .switch i {
    -webkit-box-shadow: inset 0 0 1px 1px rgb(48, 66, 106);
    box-shadow: inset 0 0 1px 1px rgb(48, 66, 106);
}

/* When switched on ... */
.bootbox-form .checkbox :checked~i, .switch :checked+i {
    -webkit-box-shadow: inset 0 0 1px rgba(0,0,0,.5), inset 0 0 40px #8a97b3;
    box-shadow: inset 0 0 1px rgba(0,0,0,.5), inset 0 0 40px #b2bfdc;
}
/* End */

/* Styled for the "text" view on the Inspect page; haven't fully looked to see if that fucked up anything else yet. MAY need to isolate it. */
pre {
    color: #b2bfdc;
    background-color: #232f48;
    border: unset;
    border-radius: unset;
}

/* Log Viewer: Begin */
/*
pre {
    color: #333;
    background-color: #f5f5f5;
    border: 1px solid #30426a;
    border-radius: 5px;
}
*/

.log_viewer {
    color: #D8DEE9;
    background-color: #1b1e2b;
    font-size: .75em;
    border: 1px solid #30426a;
    border-radius: 5px;
}

/* Highlighted line(s) in log viewer */
.log_viewer .line_selected {
    background-color: #2d3e63;
    border-left: 3px solid #f0ad4e;
}

/* End */

/* As seen in the Container details section  */
code {
    color: #BF616A;
    background-color: #1a2336;
    padding: 4px 5px 4px 5px !important;
}

/* Bar under 'Search' when on Templates page */
.searchBar ng-scope {border-bottom: 2px solid #30426a;}

/* Footer Version Number, and the 'eye' icons (i.e. 'administrators' text in tables.) */
.sidebar-footer-content .version, .fa.fa-eye-slash, .fa.fa-eye {color: #EBCB8B;}

The "applies to" filter I have is:
"Urls matching the RegEx": .*\/portainer.*
and
"Urls starting with": http://<IP_ADDRESS>:9012 (which is the LAN Ip:port of my portainer instance.)
It's not optimized yet, and I'm no CSS poobah, so some selectors could probably be combined to be smaller and cleaner, but it works for me. :p

Nice so it provides a custom CSS. We'll figure out a way to dynamically load CSS with @xAt0mZ.
In the meantime, feel free to finish that theme :-) We can probably add it as the first theme we support when it's ready.

Do you know if Stylus produces a custom CSS file that we can bundle with the app?

Stylus does have an Export button, but I've never really used it. It would probably be just as simple to save the code to a .css file and load it dynamically on user selection. And save the user's choice to a variable or something so portainer knows to keep that theme loaded.

Nice so it provides a custom CSS.

I was the one that produced the custom css, haha. :p
Stylus basically just makes sure to load that CSS you put in it if the URL matches the "applies to" pages you add. :)

Actually, I think if you just paste this into the box as a "new style" in Stylus, you can try it out instantly.
@-moz-document url-prefix("http://<IP_ADDRESS>:9012"), regexp(".*\\/portainer.*") {
/* Clean dark portainer UI

TODO::
- Templates Page: Search Bar needs work. Particularly the colors when clicked in/on.
- Events Page: Pagination.
- Users Page: The white things on the input fields are too bright.
- Exec Console needs work. (when clicking it's icon on a container in the list)
- Columns & Settings Icons, need work.
- Finish the Login box. 5px bord-rad, input backgrounds, and icon backgrounds.
- Swap Button background colors(?). i.e. the "text/tree" buttons on the Inspect pages)
----------------------------------------------- */
@import url('https://fonts.googleapis.com/css?family=Rubik&display=swap');

body {
    background: #292D3E;
    font-family: Rubik;
    color: #b2bfdc !important;
}

/* Login Panel: Begin */
.panel-body {
    background-color:#232f48;
    border: 1px solid #1b1e2b
}

.panel-default {
    border-color: #2d3e63;
}

.panel {
    background-color: #2d3e63;
}
/* End*/

/* Sidebar: Begin */
.sidebar-header a {
    color: #D8DEE9;
}

ul.sidebar .sidebar-list a.active {
    color: #E5E9F0;
    border-left: 3px solid #E5E9F0;
    background: #2d3e63;
}

ul.sidebar .sidebar-title.endpoint-name {
    color: #EBCB8B;
}

ul.sidebar .sidebar-title {
    border-bottom: 1px solid #292d3e;
    margin: 1.1em 0 0 0;
}

ul.sidebar .sidebar-list a:hover {
    color: #E5E9F0;
    border-left: 3px solid #D08770;
}
/* End */

/* Buttons: Begin */
.btn-primary {
    color: #D8DEE9;
    background-color: #286090;
    border-color: #204d74;
}

.btn-primary:hover {
    color: #D8DEE9;
    background-color: #5E81AC;
    border-color: #81A1C1;
}

.btn-primary.active.focus, .btn-primary.active:focus, .btn-primary.active:hover, .btn-primary:active.focus, .btn-primary:active:focus, .btn-primary:active:hover, .open>.dropdown-toggle.btn-primary.focus, .open>.dropdown-toggle.btn-primary:focus, .open>.dropdown-toggle.btn-primary:hover {
    color: #E5E9F0;
    background-color: #204d74;
    border-color: #122b40;
}

/* Search Box 'Button': Begin */
.btn-default:hover {
    color: #30426a;
    background-color: #1b1e2b;
}
/* End */

/* Stacks page, Tab: Begin */
.nav-tabs>li.active>a, .nav-tabs>li.active>a:focus, .nav-tabs>li.active>a:hover {
    color: #E5E9F0;
    background-color: #1b1e2b;
    border: 1px solid #30426a;
    border-bottom-color: #30426a;
}

.nav-tabs {border-bottom: 1px solid #30426a;}
/* End */

.row.header {
    height: 60px;
    background: #1B1E2B;
    margin-bottom: 15px;
}

.datatable .footer {
    background-color: #1B1E2B;
    border-radius: 0 0 5px 5px;
    color: #D8DEE9;
}

.datatable .actionBar, .datatable .toolBar {
    color: #D8DEE9;
    padding: 10px;
}

.datatable .toolBar {
    background-color: #1B1E2B;
    border-radius: 5px 5px 0 0;
}

.datatable .searchBar {
    border-top: 1px dashed #1b1e2b;
    border-bottom: 1px dashed #1b1e2b;
    background-color: #252a3c;
}

a {
    color: #81A1C1;
    text-decoration: none;
}

a:hover, a:focus, u, .btn:hover {
    color: #ECEFF4;
    text-decoration: none;
}

/* 1 Place this is used is the search bar 'button' on the Templates page ...*/
.form-control, output {
    color: #5E81AC;
    border: 1px solid #232f48 !important;
    border-radius: 5px;
}

.widget {
    -webkit-box-shadow: 0 1px 1px rgba(0,0,0,.05);
    box-shadow: 0 1px 1px rgba(0,0,0,.05);
    background: #232f48;
    border: 1px solid #1b1e2b;
    border-radius: 5px;
    /*border-color: #e9e9e9;*/
}

.widget .widget-header {
    color: #b2bfdc;
    background-color: #232f48;
    padding: 10px 15px;
    border-bottom: 1px solid #e9e9e9;
    line-height: 30px;
}

/* Text in table headers */
.widget .widget-body table thead * {color: #ECEFF4;}

/* TODO: Duped the above selector, but there are a cpl changes here.
   Designed the above on the Home tab, then the below on the Dashboard tab,
   and haven't throughougly gone through testing what it all affects. */
.widget .widget-header {
    background-color: #30426a;
    border-bottom: 1px solid #292d3e;
    border-radius: 5px 5px 0 0;
}

.text-muted {color: #bf7449;}

.widget .widget-body table thead {
    /* background: #232f48; */
    background: #1b1e2b;
}

.blocklist-item {
    border: 1px solid #1b1e2b;
    margin: 10px 0;
    -webkit-box-shadow: unset;
    box-shadow: unset;
}

/* Hovered Items in Block Lists, i.e. Endpoints List */
.blocklist-item--selected, .blocklist-item:hover {
    background-color: #2d3e63;
    color: #E5E9F0;
}

.datatable .searchIcon {
    color: #EBCB8B;
    margin-right: 5px;
}

/* Labels & Such: Begin */
.label {color: #ECEFF4;}
.label-success {background-color: #A3BE8C;}
.label-warning {background-color: #EBCB8B;}

/* Special floating for the label on the Volumes & Images pages, for aethestics */
span.label.label-warning.image-tag.ng-scope {float: right;}

.label-danger, .btn-danger {background-color: #BF616A;}
.label-primary, .btn-primary {background-color: #5E81AC;}
.fa.green-icon {color: #A3BE8C;}
.fa.red-icon, .text-danger {color: #BF616A;}
.fa.orange-icon, .text-warning {color: #D08770;}

/* "Filter" text on colunmn headers */
.widget .widget-body table thead th .table-filter {color: #EBCB8B;}

/* i.e. The circular icons on the Dashboard page */
.blue {background: #1b1e2b!important;}
/* End */

.form-control {
    width: 100%;
    height: 34px;
    padding: 6px 12px;
    background-color: #1B1E2B;
    background-image: none;
    border: 1px solid #ccc; /* hmmmm .... */
    border-radius: 4px;
    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
    box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
    -webkit-transition: border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
    transition: border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
    transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
    transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
}

.form-control, output {
    display: block;
    font-size: 14px;
    line-height: 1.42857143;
    /* color: #337ab7; */
    color: #5e81ac;
}

.table .table {background-color: rgba(0,0,0,.25);}

.table>tbody>tr>td, .table>tbody>tr>th, .table>tfoot>tr>td, .table>tfoot>tr>th, .table>thead>tr>td, .table>thead>tr>th {border-top: 1px solid #30426a;}
.table>thead>tr>th {border-bottom: 2px solid #1b1e2b;}

/* Background hover color for table items */
.table-hover>tbody>tr:hover, .table>tbody>tr.active>td, .table>tbody>tr.active>th, .table>tbody>tr>td.active, .table>tbody>tr>th.active, .table>tfoot>tr.active>td, .table>tfoot>tr.active>th, .table>tfoot>tr>td.active, .table>tfoot>tr>th.active, .table>thead>tr.active>td, .table>thead>tr.active>th, .table>thead>tr>td.active, .table>thead>tr>th.active {
    background-color: #2d3e63;
}

/* Table item borders */
.table-bordered, .table-bordered>tbody>tr>td, .table-bordered>tbody>tr>th, .table-bordered>tfoot>tr>td, .table-bordered>tfoot>tr>th, .table-bordered>thead>tr>td, .table-bordered>thead>tr>th {
    border: 1px solid #232f48;
}

.form-section-title {
    color: unset;
    border-bottom: 1px solid #2d3e63;
    margin-top: unset;
    padding-bottom: 1em;
}

#view > information-panel > div > div > rd-widget > div > rd-widget-body > div > div > div.form-group.ng-scope > ng-transclude > span,
#view > div:nth-child(3) > div > rd-widget > div > rd-widget-body > div > div > form > div:nth-child(2) > div > span {color: #D8DEE9;}

json-tree {color: unset;}

/* Colored text on the Roles page.*/
.portainer-disabled-datatable {color: #1b1e2b;}

/* Sliders/Switches: Begin */
.bootbox-form .checkbox i, .switch i {
    -webkit-box-shadow: inset 0 0 1px 1px rgb(48, 66, 106);
    box-shadow: inset 0 0 1px 1px rgb(48, 66, 106);
}

/* When switched on ... */
.bootbox-form .checkbox :checked~i, .switch :checked+i {
    -webkit-box-shadow: inset 0 0 1px rgba(0,0,0,.5), inset 0 0 40px #8a97b3;
    box-shadow: inset 0 0 1px rgba(0,0,0,.5), inset 0 0 40px #b2bfdc;
}
/* End */

/* Styled for the "text" view on the Inspect page; haven't fully looked to see if that fucked up anything else yet. MAY need to isolate it. */
pre {
    color: #b2bfdc;
    background-color: #232f48;
    border: unset;
    border-radius: unset;
}

/* Log Viewer: Begin */
/*
pre {
    color: #333;
    background-color: #f5f5f5;
    border: 1px solid #30426a;
    border-radius: 5px;
}
*/

.log_viewer {
    color: #D8DEE9;
    background-color: #1b1e2b;
    font-size: .75em;
    border: 1px solid #30426a;
    border-radius: 5px;
}

/* Highlighted line(s) in log viewer */
.log_viewer .line_selected {
    background-color: #2d3e63;
    border-left: 3px solid #f0ad4e;
}

/* End */

/* As seen in the Container details section  */
code {
    color: #BF616A;
    background-color: #1a2336;
    padding: 4px 5px 4px 5px !important;
}

/* Bar under 'Search' when on Templates page */
.searchBar ng-scope {border-bottom: 2px solid #30426a;}

/* Footer Version Number, and the 'eye' icons (i.e. 'administrators' text in tables.) */
.sidebar-footer-content .version, .fa.fa-eye-slash, .fa.fa-eye {color: #EBCB8B;}

}

Yes, we'll investigate if we can use this CSS directly into Portainer. Thanks and good job!

@STaRDoGG Easily added it to my stylus setup. Looks great! Thx!

@STaRDoGG Easily added it to my stylus setup. Looks great! Thx!

@jgwallace3 Glad ya like it. =) Still a WIP, since this code, but I've made a few new additions since then. "almost done!" lol

@STaRDoGG keep us posted when you have a finalized version and we'll start looking at this :-)

@STaRDoGG Beautiful theme! I use every website in dark mode so very much appreciate this!

Another thought might be to use custom properties and calculations for all of the colors in the stylesheet:
https://www.sitepoint.com/css-theming-custom-properties-javascript/
Then, it'd just be a matter of swapping in different variables to change the theme.  Plus, it has the added benefit of themes still working as the UI is updated in future versions of Portainer.

@STaRDoGG -
just to let you know _ I am more than likely doing it wrong... but I am unable to paste your code into a new Stylus theme.
13:1 Expected } 13:1 @import not allowed here. 333:1 Unexpected token '}'
I am unfortunately unfamiliar with this CSS stuffs... but just a FYI..

@STaRDoGG
I know... .took me 22 days to get back to this.... trying to import it in sylus; (using User CSS)
I will play with it more.... but I am so sad.

@DrDrache TY, glad you like it. =)
That line is for the custom font. I'm still learning the in's and out's of Stylus myself and still learning how it's exporting stuff works, lol.
If you want to try it with the custom font, you might be able to try this:

Disable your current one, so you can always go back to a working one if you need to.
Create a new user theme and name it whatever you want.
Use the same URLs for it as the working one.
Then just paste this code into it and save it:

Reveal code

/* Dark Portainer UI

TODO::
- Templates Page: Search Bar needs work. Particularly the colors when clicked in/on.
- Templates page: Select cat. drop-down needs work.
- Users Page: The white things on the input fields are too bright.
- Exec Console needs work. (when clicking it's icon on a container in the list)
- Finish the Login box. 5px bord-rad, input backgrounds, and icon backgrounds.
- Swap Button background colors(?). i.e. the "text/tree" buttons on the Inspect pages)
- Buttons still need work all voer the place, incl. when hovered.
----------------------------------------------- */

@import url('https://fonts.googleapis.com/css?family=Rubik&display=swap');

body {
    background: #292D3E;
    font-family: Rubik;
    color: #b2bfdc !important;
}

/* Latest News Banner */
.motd-body {
    background-color: #1b1e2b;
    border: 2px solid #f0ad4e;
    border: 2px solid #f0ad4e5c;
    border-radius: 2px;
}

/* Login Panel: Begin */
.panel-body {
    background-color:#232f48;
    border: 1px solid #1b1e2b
}

.panel-default {border-color: #2d3e63;}
.panel {background-color: #2d3e63;}
/* End*/

/* Sidebar: Begin */
.sidebar-header a {color: #D8DEE9;}

ul.sidebar .sidebar-list a.active {
    color: #E5E9F0;
    border-left: 3px solid #E5E9F0;
    background: #2d3e63;
}

ul.sidebar .sidebar-title.endpoint-name {color: #EBCB8B;}

ul.sidebar .sidebar-title {
    border-bottom: 1px solid #292d3e;
    margin: 1.1em 0 0 0;
}

ul.sidebar .sidebar-list a:hover {
    color: #E5E9F0;
    border-left: 3px solid #D08770;
}
/* End */

/* Buttons: Begin */
.btn-primary, .btn-danger, .btn-success  {
    color: #D8DEE9;
    margin-right: 1px;
}

.btn-primary {
    background-color: #286090;
    /* border-color: #204d74; */
}

.btn-primary:hover {
    background-color: #30426a;
    /* border-color: #81A1C1; */
}

.btn-danger:hover {border-color: #cc6b69;}

.btn-primary.active.focus, .btn-primary.active:focus, .btn-primary.active:hover, .btn-primary:active.focus, .btn-primary:active:focus, .btn-primary:active:hover, .open>.dropdown-toggle.btn-primary.focus, .open>.dropdown-toggle.btn-primary:focus, .open>.dropdown-toggle.btn-primary:hover {
    color: #E5E9F0;
    background-color: #204d74;
    border-color: #122b40;
}

.btn.btn-xs.btn-primary.space-left { float: right; }

/* TODO: (Following #view selectors are a bit buggy. I only want this to work in the container buttons at the top, but it is styling more than I want. Disabled for now).
/* Center the row of container control buttons */
/* #view > div:nth-child(2) > div > rd-widget > div > rd-widget-body > div {text-align: center;} */

/* Give them some room to unbutton their belts and let the fat hang out */
/* #view > div:nth-child(2) > div > rd-widget > div > rd-widget-body > div > div > div .btn-primary,
/* #view > div:nth-child(2) > div > rd-widget > div > rd-widget-body > div > div > div .btn-danger,
/* #view > div:nth-child(2) > div > rd-widget > div > rd-widget-body > div > div > div .btn-success {padding: .5em 2.5em .5em 2.5em;} */

/* Add a bit more space between the 2 sections */
/* #view > div:nth-child(2) > div > rd-widget > div > rd-widget-body > div > div > div:nth-child(2) {padding-left: 2em;} */

/* i.e. As seen in the popup Settings boxes */
.btn-default {
    color: #E5E9F0;
    background-color: #5E81AC;
    border-color: #30426a;
}

/* Search Box 'Button': Begin */
.btn-default:hover {
    color: #30426a;
    background-color: #1b1e2b;
}
/* End */

/* Drop-down Menus */
.dropdown-menu {
    /* font-size: 1em; */
    background-color: #1b1e2b;
    border: 1px solid rgb(48, 66, 106);
}

/* Text color inside of the drop-down menus. (i.e. popup settings boxes) */
.tableMenu {color: unset;}

/* Pagination: Begin */
.pagination>li>a, .pagination>li>span {
    color: #5e81ac;
    background-color: #232f48;
    border: 1px solid #232f48;
}

/* Selected */
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover, .pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover {
    color: #E5E9F0;
    background-color: #1b1e2b;
    border-color: #232f48;
}

/* Hovered */
.pagination>li>a:focus, .pagination>li>a:hover, .pagination>li>span:focus, .pagination>li>span:hover {
    z-index: 1;
    color: #E5E9F0;
    background-color: #30426a;
    border-color: #232f48;
}

/* Disabled */
.pagination>.disabled>a, .pagination>.disabled>a:focus, .pagination>.disabled>a:hover, .pagination>.disabled>span, .pagination>.disabled>span:focus, .pagination>.disabled>span:hover {
    color: #1b1e2b;
    background-color: #232f48;
    border-color: #232f48;
}
/* End */

/* Stacks page, Tab: Begin */
.nav-tabs>li.active>a, .nav-tabs>li.active>a:focus, .nav-tabs>li.active>a:hover {
    color: #E5E9F0;
    background-color: #1b1e2b;
    border: 1px solid #30426a;
}

.nav>li>a:focus, .nav>li>a:hover {
    text-decoration: none;
    background-color: #30426a;
    border: 1px solid #1b1e2b;
}

/* Keep the bottom line the same color at all times */
.nav-tabs,
.nav-tabs>li.active>a, .nav-tabs>li.active>a:focus, .nav-tabs>li.active>a:hover,
.nav>li>a:focus, .nav>li>a:hover {
    border-bottom: 1px solid #30426a;
}
/* End */

/* Big boxy things ...: Begin */
.boxselector_wrapper input[type=radio]:checked+label {
    background: #30426a;
    color: #E5E9F0;
    border-color: #1b1e2b;
}

.boxselector_wrapper label {
    background: #1c2538;
    border: 1px solid #30426a;
    -webkit-box-shadow: unset;
    box-shadow: unset;
}

.boxselector_wrapper input[type=radio]:checked+label:after {
    color: #5e81ac;
    border: 2px solid #5e81ac;
    background: #E5E9F0;
}

/* Stop that weird bouncing when selecting these */
boxselector_wrapper label {padding: 20px 10px 0;}
/* End */

.row.header {
    height: 60px;
    background: #1B1E2B;
    margin-bottom: 15px;
}

.datatable .footer {
    background-color: #1B1E2B;
    border-radius: 0 0 5px 5px;
    color: #D8DEE9;
}

.datatable .actionBar, .datatable .toolBar {
    color: #D8DEE9;
    padding: 10px;
}

.datatable .toolBar {
    background-color: #1B1E2B;
    border-radius: 5px 5px 0 0;
}

.datatable .searchBar {
    border-top: 1px dashed #1b1e2b !important;
    border-bottom: 1px dashed #1b1e2b;
    background-color: #252a3c;
}

a {
    color: #81A1C1;
    text-decoration: none;
}

a:hover, a:focus, u, .btn:hover {
    color: #ECEFF4;
    text-decoration: none;
}

/* TODO: (A bit buggy. I only want this to work in the breadcrumbs, but it is styling more than I want. Disabled for now). To make the currently chosen container's name more apparent
a.ng-binding.ng-scope {
    color: #EBCB8B;
    font-size: larger;
    text-transform: uppercase;
}
 */
/* 1 Place this is used is the search bar 'button' on the Templates page ...*/
.form-control, output {
    color: #5E81AC;
    border: 1px solid #232f48 !important;
    border-radius: 5px;
}

.widget {
    -webkit-box-shadow: 0 1px 1px rgba(0,0,0,.05);
    box-shadow: 0 1px 1px rgba(0,0,0,.05);
    background: #232f48;
    border: 1px solid #1b1e2b;
    border-radius: 5px;
    /*border-color: #e9e9e9;*/
}

.widget .widget-header {
    color: #b2bfdc;
    background-color: #232f48;
    padding: 10px 15px;
    border-bottom: 1px solid #e9e9e9;
    line-height: 30px;
}

/* Text in table headers */
.widget .widget-body table thead * {color: #ECEFF4;}

/* TODO: Duped the above selector, but there are a cpl changes here.
   Designed the above on the Home tab, then the below on the Dashboard tab,
   and haven't throughougly gone through testing what it all affects. */
.widget .widget-header {
    background-color: #30426a;
    border-bottom: 1px solid #292d3e;
    border-radius: 5px 5px 0 0;
}

.text-muted {color: #bf7449;}

.widget .widget-body table thead {
    /* background: #232f48; */
    background: #1b1e2b;
}

.blocklist-item {
    border: 1px solid #1b1e2b;
    margin: 10px 0;
    -webkit-box-shadow: unset;
    box-shadow: unset;
}

/* Hovered Items in Block Lists, i.e. Endpoints List */
.blocklist-item--selected, .blocklist-item:hover {
    background-color: #2d3e63;
    color: #E5E9F0;
}

.datatable .searchIcon {
    color: #EBCB8B;
    margin-right: 5px;
}

/* Endpoint Detals page: Begin */
.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { background-color: #30426a; }

/* Tags dropdown. TODO: Still needs work. */
#tags { background-color: #1b1e2b !important; }

/**/
.dropdown-menu>li>a { color: unset; }

/* Labels & Such: Begin */
.label {
    color: #ECEFF4;
    text-shadow: 1px 1px 1px #000000a6;
    letter-spacing: 1px;
}

.label-success {background-color: #A3BE8C;}
.label-warning {background-color: #EBCB8B;}
.label-default {background-color: #5E81AC;}
.label-info    {background-color: #D08770;}

/* The Label-info on the Networks table */
span.label.label-info.image-tag.space-left.ng-scope {float: right;}

/* Special floating for the label on the Volumes & Images pages, for aethestics */
span.label.label-warning.image-tag.ng-scope {float: right;}

.label-danger, .btn-danger     {background-color: #BF616A;}
.label-primary, .btn-primary   {background-color: #5E81AC;}
.fa.green-icon                 {color: #A3BE8C;}
.fa.red-icon, .text-danger     {color: #BF616A;}
.fa.orange-icon, .text-warning {color: #D08770;}

/* For 'healthy' containers in the Containers list, add a lil more spice */
span.label.label-success.interactive {
    color: #fbe1ad!important;
    text-shadow: 1px 1px 1px #000000a6!important;
}

/* "Filter" text on colunmn headers */
.widget .widget-body table thead th .table-filter {color: #EBCB8B;}

/* i.e. The circular icons on the Dashboard page */
.blue {background: #1b1e2b!important;}
/* End */

.form-control {
    width: 100%;
    height: 34px;
    padding: 6px 12px;
    background-color: #1B1E2B;
    background-image: none;
    border: 1px solid #ccc; /* hmmmm .... */
    border-radius: 4px;
    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
    box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
    -webkit-transition: border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
    transition: border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
    transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
    transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
}

.form-control, output {
    display: block;
    font-size: 14px;
    line-height: 1.42857143;
    /* color: #337ab7; */
    color: #5e81ac;
}

.table .table {background-color: rgba(0,0,0,.25);}

.table>tbody>tr>td, .table>tbody>tr>th, .table>tfoot>tr>td, .table>tfoot>tr>th, .table>thead>tr>td, .table>thead>tr>th {border-top: 1px solid #30426a;}
.table>thead>tr>th {border-bottom: 2px solid #1b1e2b;}

/* Background hover color for table items */
.table-hover>tbody>tr:hover, .table>tbody>tr.active>td, .table>tbody>tr.active>th, .table>tbody>tr>td.active, .table>tbody>tr>th.active, .table>tfoot>tr.active>td, .table>tfoot>tr.active>th, .table>tfoot>tr>td.active, .table>tfoot>tr>th.active, .table>thead>tr.active>td, .table>thead>tr.active>th, .table>thead>tr>td.active, .table>thead>tr>th.active {
    background-color: #2d3e63;
}

/* Background hover color for actively hovered table items */
.table-hover>tbody>tr.active:hover>td, .table-hover>tbody>tr.active:hover>th, .table-hover>tbody>tr:hover>.active, .table-hover>tbody>tr>td.active:hover, .table-hover>tbody>tr>th.active:hover {
    background-color: #5E81AC;
}

/* Table item borders */
.table-bordered, .table-bordered>tbody>tr>td, .table-bordered>tbody>tr>th, .table-bordered>tfoot>tr>td, .table-bordered>tfoot>tr>th, .table-bordered>thead>tr>td, .table-bordered>thead>tr>th {
    border: 1px solid #232f48;
}

/* i.e. As seen in the popup Settings boxes */
.tableMenu .menuContent {border-bottom: 1px solid #232f48;}
.datatable .toolBar .setting-active {color: #30426a;}

.form-section-title {
    color: unset;
    border-bottom: 1px solid #2d3e63;
    margin-top: unset;
    padding-bottom: 1em;
}

#view > information-panel > div > div > rd-widget > div > rd-widget-body > div > div > div.form-group.ng-scope > ng-transclude > span,
#view > div:nth-child(3) > div > rd-widget > div > rd-widget-body > div > div > form > div:nth-child(2) > div > span {color: #D8DEE9;}

json-tree {color: unset;}

/* Colored text on the Roles page.*/
.portainer-disabled-datatable {color: #1b1e2b;}

/* Sliders/Switches: Begin */
.bootbox-form .checkbox i, .switch i {
    -webkit-box-shadow: inset 0 0 1px 1px rgb(48, 66, 106);
    box-shadow: inset 0 0 1px 1px rgb(48, 66, 106);
}

/* When switched on ... */
.bootbox-form .checkbox :checked~i, .switch :checked+i {
    -webkit-box-shadow: inset 0 0 1px rgba(0,0,0,.5), inset 0 0 40px #8a97b3;
    box-shadow: inset 0 0 1px rgba(0,0,0,.5), inset 0 0 40px #b2bfdc;
}
/* End */

/* Styled for the "text" view on the Inspect page; haven't fully looked to see if that fucked up anything else yet. MAY need to isolate it. */
pre {
    color: #b2bfdc;
    background-color: #232f48;
    border: unset;
    border-radius: unset;
}

/* Log Viewer: Begin */
/*
pre {
    color: #333;
    background-color: #f5f5f5;
    border: 1px solid #30426a;
    border-radius: 5px;
}
*/

.log_viewer {
    color: #D8DEE9;
    background-color: #1b1e2b;
    font-size: .75em;
    border: 1px solid #30426a;
    border-radius: 5px;
}

/* Highlighted line(s) in log viewer */
.log_viewer .line_selected {
    background-color: #2d3e63;
    border-left: 3px solid #f0ad4e;
}
/* End */

/* As seen in the Container details section */
code {
    color: #BF616A;
    background-color: #1a2336;
    padding: 4px 5px 4px 5px !important;
}

/* Code Editor */

/* Allow expanding the code area vertically (as well as the lov viewer area) */
.CodeMirror, .log_viewer {
    min-height: 300px;
    resize: vertical;
    overflow: auto !important;
}

.CodeMirror-linenumber { color: #D08770; }
.CodeMirror pre { background: #ECEFF4; }
.CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler {  background-color: #ECEFF4; }

.CodeMirror-gutters {
    border-right: 1px solid #D08770;
    background-color: #EBCB8B;
}

/* Bar under 'Search' when on Templates page */
.searchBar ng-scope {border-bottom: 2px solid #30426a;}

/* NOT FINISHED: Dialogs: i.e. When deleting a container and it asks if you also want to delete non-persistant volumes */
.modal-content { background-color: #a94442; }
.modal-title { color: #ECEFF4; }
.modal-header { border-bottom: 1px solid #733b3b }
.modal-footer { border-top: 1px solid #733b3b; }

.bootbox-form label, .bootbox-body { color: #ECEFF4; }

.bootbox-form .checkbox :checked~i, .switch :checked+i {
    -webkit-box-shadow: inset 0 0 1px rgba(0,0,0,.5), inset 0 0 40px #bf616a;
    box-shadow: inset 0 0 1px rgba(0,0,0,.5), inset 0 0 40px #bf616a;
}

/* Footer Version Number, and the 'eye' icons (i.e. 'administrators' text in tables.) */
.sidebar-footer-content .version, .fa.fa-eye-slash, .fa.fa-eye { color: #EBCB8B; }

/* Table header in Services list. Could probably trim down this long selector but I'm being lazy right now. :p

TODO: change these colors, including the hover colors */
service-tasks-datatable > div > table > thead {
    background-color: #292d3e !important;
}

/* The table body for the above */
service-tasks-datatable > div > table > tbody {
    background-color: #30426a !important;
}

/* The table border for the above */
service-tasks-datatable > div {
    background-color: #30426a !important;
}

/* TESTING: trying to change background of selected text. these aren't working
.CodeMirror-selected {
    background: red;
}

.CodeMirror-focused .CodeMirror-selected {
    background: red;
}

.CodeMirror-line::selection,
.CodeMirror-line>span::selection,
.CodeMirror-line>span>span::selection {
    background: red;
}

.CodeMirror-line::-moz-selection,
.CodeMirror-line>span::-moz-selection,
.CodeMirror-line>span>span::-moz-selection {
    background: red;
} */

#toast-container { z-index: 0; }

@STaRDoGG I can confirm latest one works for me too. Thanks for sharing, I know how hard it is to get a dark theme "just right"!
Advice: maybe give each update a version number, so we know which is the latest. For e.g. maybe add a "v1" in the comments at the top of the css (in your latest post).

@STaRDoGG II know how hard it is to get a dark theme "just right"... You spent a boatload of time on this!

TYVM. =)
Yes, I have put a lot opf time into it, and you know how we are when working on these things; no matter what, it still never seems quite "finished", lol.

@STaRDoGG Thank you for this theme! This has made portainer much more pleasant to use.
One addition - I think the .modal-content needs some restyling. Tested by hitting "recreate" on a container - I've just added this clause for now:
.modal-content {
    background-color:#232f48;
}

Have you considered making a repo for this style? Might be easier to submit PRs than discuss in this thread. I think that would solve the versioning problem as well.

Agreed, another reason for a separate repo is that if your browser has a userstyles plugin installed (e.g. stylus), and you click on the theme file, it will offer to install it automatically if you click on the style file. And there is also an option to check for and install updates.

@seevee Thanks, glad you like it. =)
I never really considered making a repo for it mostly because I was more hoping that the Portainer folks would incorporate it right into Portainer itself, so it was selectable as a theme choice, but I'm not sure what (or if) their timeline is for something like that. If it's way down the road I have no gripes about making a repo for it.

Just to jump in the discussion regarding the incorporation of this, I guess this would depend on the complexity of providing a theme selector inside the app. I believe that we could potentially bundle multiple CSS files and allow the user to select one at runtime (would probably require a refresh of the app).
cc @xAt0mZ for input on this one
also cc @ncresswell for opinion

Took a quick look at it today. It would require to rework a bit the way we are building and requesting the css in the app. Regarding dyn loading, it seems to be quite easy, without app reload (found some libs doing this on npm)

@STaRDoGG As someone who's been using your Portainer CSS in Stylus for months (and just found you have updated versions) I would love if you had a repo for it.

As an update for everyone, we have this in Q4 2020 of our Roadmap which covers the next few 2.* versions of Portainer.
@STaRDoGG you're welcome to open a repo for your stylus themes for now, as it would make it easier for us to review the CSS you have when we are working on this feature and you could add a readme and such to help your above users out :stuck_out_tongue_winking_eye:
Also if you would like to talk with us about this, I see you're in our slack server so feel free to join the dev channel or message me directly

@itsconquest Sounds good, I will try to get the repo up sometime next week, time permitting.

Awesome :+1:

K guys, I whipped up a quick repo for it, with my current version of the theme. I still need to edit the readme to add more details on adding it to Stylus, but this is decent enough for now. =)
https://github.com/STaRDoGG/portainer-nord-dark-theme

That's so good. Thank you very much for making this style public. I like the default look of portainer, but dark mode always wins :D Thanks!

Bumping this thread because it seems there was no progress for a while. The theme made by @STaRDoGG looks really good, would it be enough to just add a switch to swap the CSS files?

Quick update on this topic: it's in our plans to bring theme support to Portainer later this year.

Maybe you guys know something that I don't but why doesn't portainer use a global css stylesheet?
If you use scss, you can make a workflow that auto compiles a css file when changes to the css file instead of many patch jobs. like shown in this picture.

Once you have a global file, I would think it would make it easy for users to upload their own custom CSS files in the portainer settings. Another option is to upload a link to a css file that is hosted somewhere else. This would add the possibility for people with custom themes to auto-update themes without administrators having to upload a new css file after every update.
This also might bring the opportunity for the community to make their own themes and possibly even make the site mobile-friendly.
Another benefit would be that if someone's workflow is not compatible with newer CSS, an administrator can simply use an older css file.
These are just my thoughts on this whole dark-mode theme integration.

Quick update on this topic: it's in our plans to bring theme support to Portainer later this year.

It would be a dream... tks

Been waiting for this aswell!! Gunna be exciting when it’s finally out!

Quick update on this topic: it's in our plans to bring theme support to Portainer later this year.

This is awesome. I turned on Dark Reader for my Portainer instance and was actually kinda blown away with how great it looks. Sometimes sites get mangled or have weirdness with their text when I use this extension. Might be a good starting point for a theme 😉

Quick update on this topic: it's in our plans to bring theme support to Portainer later this year.

This is awesome. I turned on Dark Reader for my Portainer instance and was actually kinda blown away with how great it looks. Sometimes sites get mangled or have weirdness with their text when I use this extension. Might be a good starting point for a theme 😉

There a theme at the top you should check out really good theme, great job to him!

We need dark mode support please!

I am using Dark Red theme (stylus) and behold how good it looks:

I am just saying that button "Upload Custom CSS" is not uncommonly seen in enterprise apps. In home apps inside docker there are these options (in configs) also common. I just hope they don't created button "dark mode" where predefined style will be used and it wont be only for non CE community.

Google Material Design
Through the inspiration of @STaRDoGG, I forked the CSS to Google's Material Design.
This will have to suffice until the real "dark mode" is available.
https://github.com/Vakrehus/portainer-materialio-dark-theme

@Vakrehus Looks nice!

Thanks a bunch for your suggestions! :D We're going introduce a dark and also high contrast theme.